Let’s look briefly at how to retrieve entities from the datastore using keys, how to inspect the contents of entities, and how to update and delete entities. The API methods for these features are straightforward.
from google.appengine.ext import db k = db.Key('Entity', 'alphabeta') e = db.get(k)
If you know the kind of the entity you are fetching, you can also
get() class method on the appropriate entity class.
This does a bit of type checking, ensuring that the key you provide is
of the appropriate kind:
class Entity(db.Expando): pass e = Entity.get(k)
To fetch multiple entities in a batch, you can pass the keys to
get() as a list. Given a list, the method returns a list
containing entity objects, with
None values for keys that
do not have a corresponding entity in the datastore.
entities = db.get([k1, k2, k3])
Getting a batch of entities in this way performs a single service call to the datastore for the entire batch. This is faster than getting each entity in a separate call. It is also subject to the service call size limit (one megabyte), so make sure the total size of all of the entities will not exceed this limit when doing a batch get. Batch gets are also subject to an entity count limit.
For convenience, entity classes include methods that take just the
IDs or key names and retrieve the corresponding entities, inferring the
kind from the class name. See
get_by_key_name() in the official reference
In the Java low-level API, you get an entity by its key using a
DatastoreService instance (returned by
instance provides a
get() method that takes a
Key for a single entity get, or an
Iterable<Key> for a batch get. If given an iterable
get() returns a
DatastoreService ds = DatastoreServiceFactory.getDatastoreService(); Map<Key, Entity> entities = ds.get(new ArrayList(Arrays.asList(k1, k2, k3))); Entity e1 = entities.get(k1);
Of course, you won’t always have the keys for the entities you want to fetch from the datastore. To retrieve entities that meet other criteria, you use datastore queries. Queries are discussed in Chapter 5.
In the Java API, the methods of the
provide straightforward access to the key (
getKind()) of the entity. The
getProperty() method returns the value of a property given
its name. The
hasProperty() method tests whether a property
setProperty() takes a name and a value and sets the
property, replacing any existing value.
is_saved() method returns
the object has not been saved to the datastore since the object was
constructed. If the object has been saved since it was constructed, or
if the object was retrieved from the datastore, the method returns
True. The method continues to return
if the object’s properties have been modified, so do not rely on this
method to track changes to properties of previously saved
e = Entity() # e.is_saved() == False e.put() # e.is_saved() == True
The Java API does not have an equivalent
In Python, entity properties can be accessed and modified just like object attributes:
e.prop1 = 1 e.prop2 = 'two' print "prop2 has the value " + e.prop2
You can use Python built-in functions for accessing object
attributes to access entity properties. For instance, to test that an
entity has a property with a given name, use the
if hasattr(e, 'prop1'): # ...
To get or set a property whose name is a string, use
# Set prop1, prop2, ..., prop9. for n in range(1, 10): value = n * n setattr(e, 'prop' + str(n), value) value = getattr(e, 'prop' + str(7))
While entity objects support accessing properties using these
methods, the objects do not actually store property values as object
attributes. For instance, you cannot use Python’s
built-in to get a list of an entity’s properties. Instead, entity
objects provide their own method,
for this purpose:
for name in e.instance_properties(): value = getattr(e, name)
In Python, calling the
put() method on an entity
object saves the entity to the datastore. If the entity does not yet
exist in the datastore,
put() creates the entity. If the
put() updates the entity so that it matches
e = Entity() e.prop = 123 e.put()
When you update an entity, the app sends the complete contents of the entity to the datastore. The update is all or nothing: there is no way to send just the properties that have changed to the datastore. There is also no way to update a property on an entity without retrieving the complete entity, making the change, then sending the new entity back.
You use the same API to create an entity as you do to update an entity. The datastore does not make a distinction between creates and updates. If you save an entity with a complete key (such as a key with a kind and a key name) and an entity already exists with that key, the datastore replaces the existing entity with the new one.
If you want to test that an entity with a given key does not exist before you create it, you can do so using the transaction API. You must use a transaction to ensure that another process doesn’t create an entity with that key after you test for it and before you create it. For more information on transactions, see Chapter 6.
If you have several entity objects to save, you can save them all
in one call using the
put() function in the
put() function can also take a single entity
db.put(e) db.put([e1, e2, e3])
In Java, you can save entities using the
DatastoreService instance. As with
method takes a single
Entity for a single put, or an
Iterable<Entity> for a batch
When the call to
put() returns, the datastore is up
to date, and all future queries in the current request handler and other
handlers will see the new data. The specifics of how the datastore gets
updated are discussed in detail in Chapter 6.
e = db.get('Entity', 'alphabeta') e.delete() db.delete(e) db.delete([e1, e2, e3]) # Deleting without first fetching the entity: k = db.Key('Entity', 'alphabeta') db.delete(k)