Reputation: 7077
Is there a good way to store a Python dictionary in the datastore? I want to do something like the following:
from google.appengine.ext import db
class Recipe(db.Model):
name = db.StringProperty()
style = db.StringProperty()
yeast = db.StringProperty()
hops = db.ListofDictionariesProperty()
Of course, that last line doesn't actually work. I need hops to be a list of key-value pairs, where the key is always a string and the value can be a string, int, or float, but I can't see anything in that would allow me to do that in the Property classes.
Upvotes: 8
Views: 4607
Reputation: 55
You can use JsonProperty. Value is a Python object (such as a list or a dict or a string) that is serializable using Python's json module; Cloud Datastore stores the JSON serialization as a blob. Unindexed by default. Optional keyword argument: compressed.
from google.appengine.ext import ndb
class Article(ndb.Model):
title = ndb.StringProperty(required=True)
stars = ndb.IntegerProperty()
tags = ndb.StringProperty(repeated=True)
info = ndb.JsonProperty()
Upvotes: 1
Reputation: 2730
I did it like this:
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)
Upvotes: 0
Reputation: 89917
Your options are basically to use pickle, to use a db.Expando and make each key in the dict a separate property, or to have a StringListProperty of keys and one of values and zip() them back to a dict when reading.
Upvotes: 1
Reputation: 15609
I'm pretty sure there's no way to store a Python dictionary. But why not just place what you'd like in hops as a second model?
Also, as mentioned by John you could use pickle, but (and correct me if I'm wrong) store it as a Blob value instead.
Upvotes: 2
Reputation: 375594
Serializing a dict with repr
is a good way to do it. You can then reconstitute it with eval
, or if you don't trust the data, a "safe eval".
An advantage of repr over pickling is that the data is readable in the database, even queryable in desperate cases.
Upvotes: 7
Reputation: 15824
You could pickle the dictionary and store it as a StringProperty.
Upvotes: 2