NDB Model Class

A class that inherits from the Model class represents the structure of entities stored in the Datastore. Applications define model classes to indicate the structure of their entities, then instantiate those model classes to create entities. All model classes must inherit (directly or indirectly) from Model.

This page has API reference documentation. For an overview, please see NDB Entities and Keys.


A class that inherits from Model describes Datastore entities.

All model classes must inherit (directly or indirectly) from Model. Straightforward assignments in the model class definition can be used to declare the model's structure:

from google.appengine.ext import ndb

class Person(ndb.Model):
  name = ndb.StringProperty()
  age = ndb.IntegerProperty()

We can now create a Person entity and write it to the Datastore:

p = Person(name='Arthur Dent', age=42)
k = p.put()

The return value from put() is a Key, which can be used to retrieve the same entity later:

p2 = k.get()
p2 == p  # Returns True

To update an entity, simply change its attributes and write it back (note that this doesn't change the key):

p2.name = 'Arthur Philip Dent'

We can also delete an entity (by using the key):


The property definitions in the class body tell the system the names and the types of the fields to be stored in the Datastore, whether they must be indexed, their default value, and more. Many different Property types exist.

The kind is normally equal to the class name (exclusive of the module name or any other parent scope). To override the kind (useful for schema changes), define a class method named _get_kind(), as follows:

  class MyModel(ndb.Model):
    def _get_kind(cls):
      return 'AnotherKind'

An application should not define two model classes with the same kind, even if they live in different modules. An application's kinds are considered a global "namespace".

Model subclasses may define pre-call and post-call hooks for most operations (get, put, delete, allocate_ids).


An application won't normally call Model(), but is likely to call the constructor of a class that inherits from Model. This creates a new instance of this model, also known as an entity.

The newly-created entity isn't automatically written to the Datastore. To make that happen, it must be written to the Datastore using an explicit call to put().


Model subclasses support these keyword arguments:

Key instance for this model. If the key parameter is used, id and parent must be None (the default).
Key id for this model. If id is used, key must be None (the default).
Key instance for the parent model or None for a top-level one. If parent is used, key must be None.
Namespace to use for this entity, or None (default) to use the current namespace. If namespace is used, key must be None.

An application can also use keyword arguments mapping to the model's properties. For example, the following works:

class Person(ndb.Model):
  name = StringProperty()
  age = IntegerProperty()

p = Person(name='Arthur Dent', age=42)

You cannot easily define a property named "key", "id", "parent", or "namespace". If you pass, for example, key="foo" in a constructor or populate() call, it sets the entity's key, not a property attribute named "key".

Note: If you override the constructor in a Model subclass, beware that the constructor is also called implicitly in some cases, and be sure that you support those calls. When an entity is read from the Datastore, an empty entity is first created by calling the constructor without arguments, after which the key and property values are set one by one. When get_or_insert() or get_or_insert_async() creates a new instance, it passes **constructor_args to the constructor, and sets the key afterwards.

Class Methods

allocate_ids(size=None, max=None, parent=None, **ctx_options)

Allocates a range of key IDs for this model class.


Number of IDs to allocate. Either size or max can be specified, not both.
Maximum ID to allocate. Either size or max can be specified, not both.
Parent key for which the IDs will be allocated.
Context options

Returns a tuple with (start, end) for the allocated range, inclusive.

An application cannot call allocate_ids() in a transaction.

allocate_ids_async(size=None, max=None, parent=None, **ctx_options)

Asynchronous version of allocate_ids.

Returns a Future object whose result is a tuple with (start, end) for the allocated range, inclusive.

get_by_id(id, parent=None, app=None, namespace=None, **ctx_options)
Returns an entity by ID. This is really just a shorthand for Key(cls, id).get().


A string or integer key ID.
Parent key of the model to get.
app (keyword arg)
ID of app. If not specified, gets data for current app.
namespace (keyword arg)
Namespace. If not specified, gets data for default namespace.
Context options

Returns a model instance or None if not found.

get_by_id_async(id, parent=None, app=None, namespace=None, **ctx_options)
Asynchronous version of get_by_id.

Returns a Future object whose result is a model instance or None if not found.

get_or_insert(key_name, parent=None, app=None, namespace=None, context_options=None, **constructor_args)
Transactionally retrieves an existing entity or creates a new one.


A Key name (i.e., a string key ID) to retrieve or create.
Parent entity key, if any.
ID of app. If not specified, gets data for current app.
Namespace. If not specified, gets data for default namespace.
Context options

This function also takes keyword arguments to pass to the constructor of the model class if an instance for the specified key name does not already exist. If an instance with the supplied key_name and parent already exists, these arguments will be discarded.

Returns existing instance of Model class with the specified key name and parent or a new one that has just been created.

This function uses a transaction. If the code that calls this function is already in a transaction, this function attempts to re-use the existing transaction. If this function's entity group is incompatible with the existing transaction, this can cause an error.

get_or_insert_async(key_name, parent=None, app=None, namespace=None, context_options=None, **constructor_args)

This is the asynchronous version of get_or_insert.

It returns a Future object whose result is an existing instance of Model class with the specified key name and parent or a new one that has just been created.

query([filter1, filter2, ...,] ancestor=None, app=None, namespace=None, filters=None, orders=None, default_options=None, projection=None distinct=False group_by=None)

Creates a Query object for this class as described in Queries.

The keyword argument distinct is shorthand for group_by = projection. All other keyword arguments are passed to the Query constructor.

If positional arguments are given, they are used to set up initial filters.

Returns a Query object.

Instance Methods


Sets values of the entity's properties. Its keyword arguments automatically recognize property names in the same way that the constructor does.


Writes the entity's data to the Datastore. Returns the entity's Key.


Context options

Asynchronously writes the entity's data to the Datastore. Returns a Future object. The Future object's result will be the entity's Key.


Context options
to_dict(include=all, exclude=None)

Returns a dict containing the model's property values. Property values for StructuredProperty and LocalStructuredProperty are recursively converted into dictionaries.


Optional list of properties to include. Default: all.
Optional list of properties to exclude. If there is overlap between include and exclude, then exclude "wins."

Note: If a property value is a mutable object (e.g. a list representing a repeated property, or a dict or list stored in a JsonProperty), unless the value is explicitly converted (e.g. in the case of a StructuredProperty), the same object is returned in the dict that is stored in the entity. In such cases, mutating the dictionary will mutate the entity, and vice versa.

Instance Data

Special property to store the Model key.

Hook Methods

An application's subclass of Model can define one or more of these methods as pre- or post- operation "hook" methods. E.g., to run some code before each "get", define the model subclass' _pre_get_hook() method. For advice on writing hook functions, see Model Hooks.

_pre_allocate_ids_hook(cls, size, max, parent)
Hook that runs before allocate_ids()
_post_allocate_ids_hook(cls, size, max, parent, future)
Hook that runs after allocate_ids()
_pre_delete_hook(cls, key)
Hook that runs before delete()
_post_delete_hook(cls, key, future)
Hook that runs after delete()
_pre_get_hook(cls, key)
Hook that runs before Key.get() when getting an entity of this model.
_post_get_hook(cls, key, future)
Hook that runs after Key.get() when getting an entity of this model.
Hook that runs before put()
_post_put_hook(self, future)
Hook that runs after put()


You can use these methods to inspect the properties and configuration of a given model. This is useful if you're writing a library or function that accepts multiple types of models.

Lookup by kind

Every model has a kind that is usually the same as the class name unless overridden. You can use the kind to find the associated model class by using _lookup_model.

class Animal(ndb.Model):
    type = ndb.StringProperty()

print Animal._get_kind()  # 'Animal'
print ndb.Model._lookup_model('Animal')  # class Animal

Note that _lookup_model only works for model classes that have already been imported by the application.


You can get a list of all properties associated with a model using _properties.

class User(ndb.Model):
    name = ndb.StringProperty()
    email = ndb.StringProperty()

print User._properties
# {'email': StringProperty('email'), 'name': StringProperty('name')}

_properties also works for Expando instances.

class Example(ndb.Expando):

e = Example()
e.foo = 1
e.bar = 'blah'
e.tags = ['exp', 'and', 'oh']
print e._properties
# {'foo': GenericProperty('foo'), 'bar': GenericProperty('bar'),
# 'tags': GenericProperty('tags', repeated=True)}

Property instances can be introspected. The options provided to the constructor are available as _-prefixed properties.

print User._properties['email']._name  # 'email'
print User._properties['email']._required  # False
print User._properties['email']._default  # None
print User._properties['email']._choices  # None
print User._properties['email']._compressed  # False
print User._properties['email']._indexed  # True
print User._properties['email']._compressed  # False
print User._properties['email']._repeated  # False
print User._properties['email']._verbose_name  # None
print isinstance(User._properties['email'], ndb.StringProperty)  # True

Method Aliases

Every method in the Model class has a _-prefixed alias. For example, _put() is equivalent to put(). This means that you can have properties with names that conflict with method names provided you always use the _-prefixed methods. However, note that you can not specify any properties named key, parent, or id in the constructor.

class MyModel(ndb.Model):
    put = ndb.StringProperty()
    query = ndb.StringProperty()
    key = ndb.StringProperty()

entity = MyModel()
entity.put = '1'
entity.query = '2'
entity.key = '3'

print entity
# MyModel(key=Key('MyModel', ...), put=u'1', query=u'2', key=u'3')

print MyModel._query().fetch()
# same as above.

If you are creating third-party libraries that interact with arbitrary models, using the _-prefixed methods is recommended.