Skip to content

Query Reference

Query builder for the Google Cloud Datastore ODM.

This module is structured into three layers
  • AST Nodes: Simple objects that represent filter/order logic.
  • Logic Functions: Global AND/OR helpers to group Nodes.
  • Query Engine: The main class that translates Nodes into Datastore SDK calls.

Query(model_cls, project=None, database=None, namespace=None)

Bases: Generic[TModel]

The main Query builder for fetching entities from Google Cloud Datastore.

This class provides a fluent, chainable API for building complex Datastore queries using Python-native property comparisons.

projection(*args)

Sets the projection fields for the query.

Projection queries are significantly faster and cheaper because they only retrieve specific fields from the Datastore rather than the entire entity.

Parameters:

Name Type Description Default
*args str | Property

The properties to retrieve.

()

Returns:

Name Type Description
Query Query[TModel]

The chainable query instance.

Examples:

# Fetch only the email addresses of all users
users = User.query().projection(User.email).fetch()

distinct_on(*args)

Sets the fields to use for grouping distinct results.

Parameters:

Name Type Description Default
*args str | Property

The properties to group by.

()

Returns:

Name Type Description
Query Query[TModel]

The chainable query instance.

Examples:

# Find all unique countries users are from
unique_countries = User.query().distinct_on(User.country).fetch()

keys_only()

Marks the query to return only Datastore Keys instead of full entities.

Keys-only queries are incredibly fast and cost-effective. Use them when you only need to check for existence or perform batch deletions.

Returns:

Name Type Description
Query Query[TModel]

The chainable query instance.

filter(*args)

Adds filters to the query.

Supports both standard ODM Property comparisons (recommended) and raw string passthrough for edge cases.

Parameters:

Name Type Description Default
*args Node | str

Filter nodes generated by comparing properties, or three raw strings (name, operator, value) for passthrough.

()

Returns:

Name Type Description
Query Query[TModel]

The chainable query instance.

Raises:

Type Description
ValueError

If the arguments are malformed.

Examples:

# Standard Property comparison
q = User.query().filter(User.age >= 18)

# Multiple implicit AND filters
q = User.query().filter(User.age >= 18, User.is_active == True)

# Composite Logic
q = User.query().filter(OR(User.role == "admin", User.score > 100))

order(*args)

Adds ordering/sorting to the query.

Supports unary operators (- for descending, + for ascending) directly on properties, or raw string field names.

Parameters:

Name Type Description Default
*args OrderNode | str | Property

The properties to sort by.

()

Returns:

Name Type Description
Query Query[TModel]

The chainable query instance.

Examples:

# Sort by highest score first, then alphabetically by name
q = User.query().order(-User.score, User.name)

fetch(limit=None)

Executes the query and yields results.

Parameters:

Name Type Description Default
limit int | None

The maximum number of results to return.

None

Yields:

Type Description
TModel | Key

Model | datastore.Key: Hydrated model instances, or Datastore Keys

TModel | Key

if keys_only() was called.

Examples:

for user in User.query().filter(User.age > 18).fetch(limit=50):
    print(user.name)

fetch_page(page_size, start_cursor=None)

Fetches a specific page of results, returning metadata needed for pagination.

Parameters:

Name Type Description Default
page_size int

The maximum number of entities to retrieve in this page.

required
start_cursor bytes | None

The pagination cursor from a previous call.

None

Returns:

Type Description
tuple[list[TModel | Key], bytes | None, bool]

A tuple containing three elements (results, next_cursor, has_more)

  • results: A list of hydrated instances (or Keys).
  • next_cursor: The byte string cursor for the next page, or None if finished.
  • has_more: True if there are more entities remaining, otherwise False.

Examples:

q = User.query().order(User.name)

cursor = None
while True:
    page, cursor, has_more = q.fetch_page(page_size=20, start_cursor=cursor)
    process_users(page)

    if not has_more:
        break

get()

Executes the query and returns the first matching result.

Automatically applies a limit=1 to the query to ensure maximum efficiency.

Returns:

Type Description
TModel | Key | None

Model | datastore.Key | None: The first matching instance, or None if the query returned zero results.

Examples:

first_admin = User.query().filter(User.role == "admin").get()

count()

Performs a fast server-side count aggregation.

This delegates the counting operation to Google's backend, making it infinitely more scalable and cost-effective than fetching and counting entities locally.

Returns:

Name Type Description
int int

The total number of matching entities.

sum(property_field)

Performs a fast server-side sum aggregation on a specific property.

Parameters:

Name Type Description Default
property_field str | Property

The property to sum.

required

Returns:

Type Description
int | float

int | float: The total sum. Returns 0 if no entities matched.

avg(property_field)

Performs a fast server-side average aggregation on a specific property.

Parameters:

Name Type Description Default
property_field str | Property

The property to average.

required

Returns:

Type Description
float | None

float | None: The average value, or None if no entities matched.

aggregate(**kwargs)

Performs multiple aggregations in a single Datastore RPC call.

Parameters:

Name Type Description Default
**kwargs CountAggregation | SumAggregation | AvgAggregation

Alias names mapped to Google Datastore Aggregation objects (Count, Sum, or Avg).

{}

Returns:

Type Description
dict[str, Any]

dict[str, Any]: A dictionary mapping your aliases to their aggregated values.

Examples:

from google.cloud.datastore.aggregation import CountAggregation as Count
from google.cloud.datastore.aggregation import SumAggregation as Sum

stats = Article.query().aggregate(
    total_articles=Count(),
    total_views=Sum(Article.views)
)
print(stats["total_views"])

and_(*filters)

Combines multiple filters with AND logic.

Parameters:

Name Type Description Default
*filters Node

Two or more filter nodes.

()

Returns:

Name Type Description
CompositeNode CompositeNode

A logical AND grouping of the filters.

Examples:

q = User.query().filter(and_(User.age >= 18, User.status == "active"))

or_(*filters)

Combines multiple filters with OR logic.

Parameters:

Name Type Description Default
*filters Node

Two or more filter nodes.

()

Returns:

Name Type Description
CompositeNode CompositeNode

A logical OR grouping of the filters.

Examples:

q = User.query().filter(or_(User.role == "admin", User.role == "editor"))

AND = and_ module-attribute

OR = or_ module-attribute