8
votes

Comment puis-je mettre un dictionnaire dans le magasin de données?

Y a-t-il un bon moyen de stocker un dictionnaire Python dans le magasin de données? Je veux faire quelque chose comme ce qui suit:

from google.appengine.ext import db

class Recipe(db.Model):
  name = db.StringProperty()
  style = db.StringProperty()
  yeast = db.StringProperty()
  hops = db.ListofDictionariesProperty()


0 commentaires

7 Réponses :


2
votes

Vous pouvez Pickle le dictionnaire et le stocker comme une stringproperty.


0 commentaires

7
votes

sérialiser un dict avec REC est un bon moyen de le faire. Vous pouvez ensuite le reconstituer avec eval ou si vous ne faites pas confiance aux données, un " EVAL SAFE ".

Un avantage de la reproduction sur le décapage est que les données sont lisibles dans la base de données, même interrogées dans des cas désespérés.


5 commentaires

JSON est généralement plus sûr que Eval.


Je n'aurai probablement pas besoin d'interroger ce champ, mais j'aime bien cela j'ai la possibilité. Aussi, corrigez-moi si je me trompe, mais n'utiliserais pas RECI et utiliser JSON a la même sortie dans ce cas?


Même avec "Safe Eval", REC pourrait être dangereux. Guido lui-même doute que vous pourriez écrire une telle fonction. Voir code.google.com/p/googleAppengine/issues/detail?id = 671 . JSON est plus simple que Python, et j'ai plus de confiance qu'un analyseur JSON ne serait pas vulnérable de la manière dont eval peut être.


JSON est la meilleure solution ici, mais pour le compte rendu, vous pouvez écrire une évaluation sûre qui désérialisera des dictes de valeurs primitives en toute sécurité.


JSON nécessite des frais généraux pour certaines propriétés. Par exemple, vous ne pouvez pas simplement utiliser JSON pour sérialiser les valeurs DateTimeProperty.



2
votes

Je suis à peu près sûr qu'il n'y a aucun moyen de stocker un dictionnaire Python. Mais pourquoi ne pas simplement placer ce que vous aimeriez au houblon comme deuxième modèle?

Aussi, comme mentionné John, vous pouvez utiliser Pickle, mais (et me corriger si je me trompe) le stocke comme un Blob à la place.


1 commentaires

@Bartek, vous pouvez utiliser les décharges et charges du module de cornichon pour fonctionner avec des chaînes: >>> cpickle.loads (cpickle.dumps ({1: "One"})) {1: "One '}



1
votes

Vos options sont essentiellement pour utiliser le cornichon, pour utiliser un db.expando et faire chaque clé dans la propriété DICT une propriété distincte, ou pour avoir une source de protection des clés et une des valeurs et de la fermeture zip vers une dicte lors de la lecture .


0 commentaires

7
votes

Vous pouvez utiliser JSON


2 commentaires

@gnibbler: convertir le dict dans le format JSON et stockez-le sous forme de db.stringproperty ?


@Kit, oui. En plus d'être plus sûr que RECER / EVAL et vous permet d'écrire un "SAFY EVAL", JSON est plus portable si vous vous trouvez en utilisant une langue différente à un moment donné



0
votes

Je l'ai fait comme ceci:

class MyEntity(db.Model):
    dictionary_string = db.StringProperty()

payload = {{}...{}}

# Store dict
my_entity = MyEntity(key_name=your_key_here)
my_entity.dictionary_string = str(payload)
my_entity.put()

# Get dict
import ast
my_entity_k = db.Key.from_path('MyEntity', your_key_here)
my_entity = db.get(my_entity_k)
payload = ast.literal_eval(my_entity.dictionary_string)


0 commentaires