Python 2.7 has reached end of supportand will bedeprecatedon January 31, 2026. After deprecation, you won't be able to deploy Python 2.7applications, even if your organization previously used an organization policy tore-enable deployments of legacy runtimes. Your existing Python2.7 applications will continue to run and receive traffic after theirdeprecation date. We recommend thatyoumigrate to the latest supported version of Python.

Datastore Queries

Note:Developers building new applications arestrongly encouraged to use theNDB Client Library, which has several benefitscompared to this client library, such as automatic entity caching via the MemcacheAPI. If you are currently using the older DB Client Library, read theDB to NDB Migration Guide

A Datastorequery retrievesentities from Cloud Datastore that meet a specified set of conditions.

A typical query includes the following:

  • Anentity kind to which the query applies
  • Optionalfilters based on the entities' property values, keys, and ancestors
  • Optionalsort orders to sequence the results
When executed, a query retrieves all entities of the given kind that satisfyall of the given filters, sorted in the specified order. Queries execute as read-only.

This page describes the structure and kinds of queries used within App Engine toretrieve data from Cloud Datastore.

Filters

A query'sfilters set constraints on theproperties,keys, andancestors of the entities to be retrieved.

Property filters

Aproperty filter specifies

  • A property name
  • A comparison operator
  • A property value
For example:

q=Person.all()q.filter("height <=",max_height)

The property value must be supplied by the application; it cannot refer to orbe calculated in terms of other properties. An entity satisfies the filter if ithas a property of the given name whose value compares to the value specified inthe filter in the manner described by the comparison operator.

The comparison operator can be any of the following:

OperatorMeaning
=Equal to
<Less than
<=Less than or equal to
>Greater than
>=Greater than or equal to
!= Not equal to
IN Member of (equal to any of the values in a specified list)

The not-equal (!=) operator actually performs two queries: one in which all other filters areunchanged and the not-equal filter is replaced with a less-than (<) filter, and one where it is replaced with a greater-than (>) filter. The results are then merged, in order. A query can have no more than one not-equal filter, and a query that has one cannot have any other inequality filters.

TheIN operator also performs multiplequeries: one for each item in the specified list, with all other filtersunchanged and theIN filter replaced with an equality (=) filter. The results are merged in order of the items in the list. If a query hasmore than oneIN filter, it is performed asmultiple queries, one for each possiblecombination of values in theIN lists.

A single query containing not-equal (!=) orIN operators is limited to a maximum of 30 subqueries.

Key filters

To filter on the value of an entity's key, use the special property__key__:

q=Person.all()q.filter('__key__ >',last_seen_key)

When comparing for inequality, keys are ordered by the following criteria, in order:

  1. Ancestor path
  2. Entity kind
  3. Identifier (key name or numeric ID)

Elements of the ancestor path are compared similarly: by kind (string), thenby key name or numeric ID. Kinds and key names are strings and are ordered bybyte value; numeric IDs are integers and are ordered numerically. If entitieswith the same parent and kind use a mix of key name strings and numeric IDs,those with numeric IDs precede those with key names.

Queries on keys use indexes just like queries on properties and requirecustom indexes in the same cases, with a couple of exceptions: inequalityfilters or an ascending sort order on the key do not require a custom index, buta descending sort order on the key does. As with all queries, the development web server creates appropriate entries in theindex configuration file when a query that needs a custom index is tested.

Ancestor filters

You can filter your Datastore queries to a specifiedancestor, so that the results returned will include only entities descended from that ancestor:

q=Person.all()q.ancestor(ancestor_key)
Caution: PassingNone as the ancestor key doesnot query forroot entities (those without ancestors). This type of query is not currentlysupported and will return an error.

Special query types

Some specific types of query deserve special mention:

Kindless queries

A query with no kind and no ancestor filter retrieves all of the entities of an application from Datastore. This includes entities created and managed by other App Engine features, such asstatistics entities andBlobstore metadata entities (if any). Suchkindless queries cannot include filters or sort orders on property values. They can, however, filter on entity keys by specifying__key__ as the property name:

q=db.Query()q.filter('__key__ >',last_seen_key)

In Python, every entity returned by the query must have a correspondingmodel class defined for the entity's kind. To define the model classes for the statistics entity kinds, you must import thestats package:

fromgoogle.appengine.ext.dbimportstats

If your application has a Blobstore value, you must add the following code to get the query API to recognize the__BlobInfo__ entity kind. (Importing the Blobstore API does not define this class.)

fromgoogle.appengine.extimportdbclassBlobInfo(db.Expando):@classmethoddefkind(cls):return'__BlobInfo__'

Ancestor queries

A query with anancestor filter limits its results to the specified entity and its descendants:

tom=Person(key_name='Tom')wedding_photo=Photo(parent=tom)wedding_photo.image_url='http://domain.com/some/path/to/wedding_photo.jpg'wedding_photo.put()baby_photo=Photo(parent=tom)baby_photo.image_url='http://domain.com/some/path/to/baby_photo.jpg'baby_photo.put()dance_photo=Photo(parent=tom)dance_photo.image_url='http://domain.com/some/path/to/dance_photo.jpg'dance_photo.put()camping_photo=Photo()camping_photo.image_url='http://domain.com/some/path/to/camping_photo.jpg'camping_photo.put()photo_query=Photo.all()photo_query.ancestor(tom)# This returns wedding_photo, baby_photo, and dance_photo,# but not camping_photo, because tom is not an ancestorforphotoinphoto_query.run(limit=5):# Do something with photo
Note: Setting anancestor filter allows for strongly consistent queries. Queries without an ancestor filter only return eventually consistent results.

Kindless ancestor queries

A kindless query that includes an ancestor filter will retrieve the specifiedancestor and all of its descendants, regardless of kind. This type of query doesnot require custom indexes. Like all kindless queries, it cannot include filtersor sort orders on property values, but can filter on the entity's key:

q=db.Query()q.ancestor(ancestor_key)q.filter('__key__ >',last_seen_key)

To perform a kindless ancestor query using GQL (either in the App Engine Administration Console or using theGqlQuery class), omit theFROM clause:

q=db.GqlQuery('SELECT * WHERE ANCESTOR IS :1 AND __key__ > :2',ancestor_key,last_seen_key)
Note: You can use thedb.query_descendants() function to return a query for all descendants of a given entity.

The following example illustrates how to retrieve all entities descended froma given ancestor:

tom=Person(key_name='Tom')wedding_photo=Photo(parent=tom)wedding_photo.image_url='http://domain.com/some/path/to/wedding_photo.jpg'wedding_photo.put()wedding_video=Video(parent=tom)wedding_video.video_url='http://domain.com/some/path/to/wedding_video.avi'wedding_video.put()# The following query returns both weddingPhoto and weddingVideo,# even though they are of different entity kindsmedia_query=db.query_descendants(tom)formediainmedia_query.run(limit=5):# Do something with media

Keys-only queries

Akeys-only query returns just the keys of the result entitiesinstead of the entities themselves, at lower latency and cost than retrievingentire entities:

q=Person.all(keys_only=True)

It is often more economical to do a keys-only query first, and then fetch a subset of entitiesfrom the results, rather than executing a general query which may fetch more entities than youactually need.

Projection queries

Sometimes all you really need from the results of a query are the values of afew specific properties. In such cases, you can use aprojection queryto retrieve just the properties you're actually interested in, at lower latencyand cost than retrieving the entire entity; see theProjection Queries page for details.

Sort orders

A querysort order specifies

  • A property name
  • A sort direction (ascending or descending)

In Python, descending sort order is denoted by a hyphen (-)preceding the property name; omitting the hyphen specifies ascending order bydefault. For example:

# Order alphabetically by last name:q=Person.all()q.order('last_name')# Order by height, tallest to shortest:q=Person.all()q.order('-height')

If a query includes multiple sort orders, they are applied in the sequencespecified. The following example sorts first by ascending last name and then bydescending height:

q=Person.all()q.order('lastName')q.order('-height')

If no sort orders are specified, the results are returned in the order theyare retrieved from Datastore.

Note: Because of the wayDatastore executes queries, if a query specifies inequality filters on aproperty and sort orders on other properties, the property used in theinequality filters must be ordered before the other properties.

Indexes

Every Datastorequery computes its results using one or moreindexes, which contain entity keys in a sequence specified by the index's propertiesand, optionally, the entity's ancestors. The indexes are updated incrementallyto reflect any changes the application makes to its entities, so that thecorrect results of all queries are available with no further computationneeded.

App Engine predefines a simple index on each property of an entity.An App Engine application can define further custom indexes in anindexconfiguration file namedindex.yaml. The development server automaticallyadds suggestions to this file as it encounters queries that cannot be executed with the existing indexes.You can tune indexes manually by editing the file before uploading the application.

Query interface example

The Python Datastore API provides two classes for preparing and executingqueries:

  • Query uses method calls to prepare the query.
  • GqlQuery uses a SQL-like query language called GQL to prepare the query from a query string.
classPerson(db.Model):first_name=db.StringProperty()last_name=db.StringProperty()city=db.StringProperty()birth_year=db.IntegerProperty()height=db.IntegerProperty()# Query interface constructs a query using instance methodsq=Person.all()q.filter("last_name =","Smith")q.filter("height <=",max_height)q.order("-height")# GqlQuery interface constructs a query using a GQL query stringq=db.GqlQuery("SELECT * FROM Person "+"WHERE last_name = :1 AND height <= :2 "+"ORDER BY height DESC","Smith",max_height)# Query is not executed until results are accessedforpinq.run(limit=5):print"%s%s,%d inches tall"%(p.first_name,p.last_name,p.height)
Note: The properties being filtered on must have a corresponding predefined index which can be defined in yourindex configuration file (index.yaml).

What's next?

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2025-12-15 UTC.