English | Site Directory

Keys and Entity Groups

Every entity in the datastore has a key, an identifier unique to the entity across all entities for an application. A key has several components: a path describing a parent-child relationship between the entity and another entity, the kind of the entity, and either a name assigned to the entity by the application or a numeric ID assigned by the datastore.

Kinds, Names and IDs

Every entity is of a particular kind, a group of entities that can be returned by a query. Unlike rows in a table, two entities of the same kind need not have the same properties, though an application can establish such a restriction in a data model. The datastore API uses the name of the Model (or Expando) subclass as the name of the kind.

For example, this class defines a model for a kind named "Story":

class Story(db.Model):
  title = db.StringProperty()
  author = db.StringProperty()

Every entity has an identifier. An application can assign its own identifier for use in the key by giving the instance constructor a key_name argument (a str value):

s = Story(key_name="xzy123")

A key_name is stored as a Unicode string (with str values converted as ASCII text). A key_name must not start with a number, and must not be of the form __*__ (start and end with two underscores). If your application uses user-submitted data as datastore entity key names (such as an email address), the application should sanitize the value first, such as by prefixing it with a known string, to meet these requirements.

If a key_name is not specified, the entity is assigned a numeric ID when it is first stored in the datastore.

s2 = Story()    # s2 does not have a name or an ID.
s2.put()        # s2 is given an ID by the datastore.

Once the entity has been created, its ID or name cannot be changed.

Tip: Key names and IDs cannot be used like property values in queries. However, you can use a named key, then store the name as a property. You could do something similar with numeric IDs by storing the object to assign the ID, getting the ID value using obj.key().id(), setting the property with the ID, then storing the object again.

Entity Groups, Ancestors and Paths

Every entity belongs to an entity group, a set of one or more entities that can be manipulated in a single transaction. Entity group relationships tell App Engine to store several entities in the same part of the distributed network. A transaction sets up datastore operations for an entity group, and all of the operations are applied as a group, or not at all if the transaction fails.

When the application creates an entity, it can assign another entity as the parent of the new entity. Assigning a parent to a new entity puts the new entity in the same entity group as the parent entity.

An entity without a parent is a root entity. An entity that is a parent for another entity can also have a parent. A chain of parent entities from an entity up to the root is the path for the entity, and members of the path are the entity's ancestors. The parent of an entity is defined when the entity is created, and cannot be changed later.

Every entity with a given root entity as an ancestor is in the same entity group. All entities in a group are stored in the same datastore node. A single transaction can modify multiple entities in a single group, or add new entities to the group by making the new entity's parent an existing entity in the group.

For more information about transactions, see Transactions.

If an entity that is an ancestor of another entity is deleted, the descendant entity is not deleted. The descendant entity is still accessible using its complete Key or path.

You can create an entity with an ancestor path without first creating the parent entity. To do so, you create a Key for the ancestor using a kind and key name, then use it as the parent of the new entity. All entities with the same root ancestor belong to the same entity group, whether or not the root of the path represents an actual entity.

Tips for using entity groups:

  • Only use entity groups when they are needed for transactions. For other relationships between entities, use ReferenceProperty properties and Key values, which can be used in queries.
  • The more entity groups your application has—that is, the more root entities there are—the more efficiently the datastore can distribute the entity groups across datastore nodes. Better distribution improves the performance of creating and updating data. Also, multiple users attempting to update entities in the same entity group at the same time will cause some users to retry their transactions, possibly causing some to fail to commit changes. Do not put all of the application's entities under one root.
  • A good rule of thumb for entity groups is that they should be about the size of a single user's worth of data or smaller.
  • Entity groups do not have a significant impact on the speed of queries.

Paths and Key Uniqueness

The complete key of an entity, including the path, the kind and the name or numeric ID, is unique and specific to that entity. The complete key is assigned when the entity is created in the datastore, and none of its parts can change.

The keys of two different entities can have similar parts as long as at least one part is different. For instance, two entities can have the same kind and name if they have different parents. Similarly, two entities can have the same parent (or no parent) and name if they are of different kinds.

An application should not rely on numeric IDs being assigned in increasing order with the order of entity creation. This is generally the case, but not guaranteed.