google.appengine.ext.ndb.msgprop module


MessageProperty – a property storing ProtoRPC Message objects.

Basic usage:

Let’s assume you have a protorpc.messages.Message subclass, like this:

from protorpc import messages

class Note(messages.Message):

text = messages.StringField(1, required=True) when = messages.IntegerField(2)

Now suppose you’d like to store Notes in Cloud Datastore. Create a model class to hold your notes, as follows:

from google.appengine.ext import ndb from google.appengine.ext.ndb import msgprop

class NoteStore(ndb.Model):

note = msgprop.MessageProperty(Note) name = ndb.StringProperty()

(The class name, ‘NoteStore’, and the property name, ‘note’, are yours to choose.)

To store, a Note message, create a NoteStore entity and write it:

ns = NoteStore(note=my_note, name=’foo’) key = ns.put()

To later retrieve the Note, read the NoteStore entity back:

ns = key.get() my_note = ns.note

The MessageProperty class has many of the usual Property options:
  • name: optional datastore name

  • repeated: if True, stores a list of message values

  • required: if True, the message value cannot be None

  • default: optional default message value to store

  • choices: optional list of allowed choices (must all be messages)

  • validator: optional function to validate message values

  • verbose_name: optional long name for the property

However, MessageProperty does not support the ‘indexed’ option. Instead, you can specify a list of field names that will be indexed, like this:

class MyStore(ndb.Model):

author = ndb.StringProperty() note = msgprop.MessageProperty(Note, indexed_fields=[‘text’, ‘when’])

Now you can query for field values, like this:

stores = MyStore.query(MyStore.note.when >= 123).fetch()

Note the similarity with StructuredProperty – in fact, MessageProperty inherits from StructuredProperty. The main difference is that StructuredProperty takes an Model subclass instead of a protorpc.messages.Message subclass; and StructuredProperty doesn’t index any fields by default.

It works for nested messages (using MessageField) as well:

class Notes(messages.Message):

notes = messages.MessageField(Note, 1, repeated=True)

class MyNotesStore(ndb.Model):

author = ndb.StringProperty() foo = msgprop.MessageProperty(Notes,

indexed_fields=[‘notes.text, ‘notes.when’])

And given this value for indexed_fields, in this example you can also query for subfields:

stores = MyNoteStore.query( < 123).fetch()

A final option for MessageProperty is ‘protocol’. This lets you specify how the message object is serialized to Cloud Datastore. The values are protocol names as used by protorpc.remote.Protocols class. Supported protocol names are ‘protobuf’ and ‘protojson’; the default is ‘protobuf’. (In the future this will use the global protocols registry that is being added to protorpc; then any registered protocol name will be acceptable.)

There is also an EnumProperty, which can be used to store a messages.Enum value without wrapping it in a Message object. Example:

class Color(messages.Enum):

RED = 620 GREEN = 495 BLUE = 450

class Part(ndb.Model):

name = ndb.StringProperty() color = msgprop.EnumProperty(Color, required=True)

p1 = Part(name=’foo’, color=Color.RED) key1 = p1.put() … p2 = key1.get() print, p2.color # prints “foo RED”

The EnumProperty stores the value as an integer; in fact, EnumProperty is a subclass of IntegerProperty. This is handy to know, since it implies that you can rename your enum values without having to modify already-stored entities, but you cannot renumber them.

The EnumProperty supports the following standard options:
  • name

  • indexed

  • repeated

  • required

  • default

  • choices

  • validator

  • verbose_name


class google.appengine.ext.ndb.msgprop.MessageProperty(*args, **kwds)source

Bases: google.appengine.ext.ndb.model.StructuredProperty

Messages are represented in Cloud Datastore as structured properties.

By default, the structured property has a single subproperty containing the serialized message. This property is named ‘blob_’ in Python but __<protocol>__ in the Datastore, where <protocol> is the value of the protocol argument (default ‘protobuf’).

class google.appengine.ext.ndb.msgprop.EnumProperty(*args, **kwds)source

Bases: google.appengine.ext.ndb.model.IntegerProperty

Enums are represented in Cloud Datastore as integers.

While this is less user-friendly in the Datastore viewer, it matches the representation of enums in the protobuf serialization (although not in JSON), and it allows renaming enum values without requiring changes to values already stored in the Datastore.