Dan Hook
Dan Hook

Reputation: 7077

How do I put a dictionary in the datastore?

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

Answers (7)

Roy Yin
Roy Yin

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

MdaG
MdaG

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

John La Rooy
John La Rooy

Reputation: 304205

You can use json

Upvotes: 7

Wooble
Wooble

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

Bartek
Bartek

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

Ned Batchelder
Ned Batchelder

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

John Paulett
John Paulett

Reputation: 15824

You could pickle the dictionary and store it as a StringProperty.

Upvotes: 2

Related Questions