8

¿Hay una buena manera de almacenar un diccionario de Python en el almacén de datos? Quiero hacer algo como lo siguiente:¿Cómo coloco un diccionario en el almacén de datos?

from google.appengine.ext import db 

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

Por supuesto, esa última línea en realidad no funciona. Necesito saltos para ser una lista de pares clave-valor, donde la clave siempre es una cadena y el valor puede ser una cadena, int o float, pero no puedo ver nada que me permita hacer eso en el Property classes.

Respuesta

7

Serializar un dict con repr es una buena manera de hacerlo. A continuación, puede reconstituirlo con eval, o si no confía en los datos, un "safe eval".

Una ventaja de repr over pickling es que los datos son legibles en la base de datos, incluso se pueden consultar en casos desesperados.

+1

JSON es generalmente más seguro que eval. –

+0

Probablemente no necesite consultar ese campo, pero me gusta que tenga la opción. Además, corrígeme si me equivoco, pero ¿no usaría repr y usaría JSON el mismo resultado en este caso? –

+0

Incluso con "evaluación segura", 'repr' podría ser peligroso. El mismo Guido duda que puedas escribir esa función. Ver http://code.google.com/p/googleappengine/issues/detail?id=671. JSON es más simple que python, y tengo más confianza en que un analizador JSON no sería vulnerable en la forma en que 'eval' puede ser. – lemnar

2

Puede pickle el diccionario y almacenarlo como StringProperty.

2

Estoy bastante seguro de que no hay forma de almacenar un diccionario de Python. Pero ¿por qué no simplemente colocar lo que le gustaría en lúpulos como segundo modelo?

Además, como menciona John, podría usar pickle, pero (y corríjame si me equivoco) almacénelo en su lugar como un valor Blob.

+1

@Bartek, puede usar las funciones de volcado y carga del módulo Pickle para trabajar con cadenas: >>> cPickle.loads (cPickle.dumps ({1: "one"})) {1: 'one'} – Mark

1

Sus opciones son básicamente usar pickle, usar un db.Expando y hacer que cada clave en el dict sea una propiedad separada, o tener una StringListProperty de claves y uno de los valores y zip() volver a un dict cuando leyendo.

7

Puede utilizar JSON

+0

+1: reglas de JSON. –

+1

@gnibbler: ¿Convierte el 'dict' en formato JSON y lo almacena como' db.StringProperty'? – Kit

+0

@Kit, sí. Además de ser más seguro que repr/eval y le permite escribir una "evaluación segura", JSON es más portátil si se encuentra utilizando un idioma diferente en algún momento –

0

lo hice así:

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) 
Cuestiones relacionadas