Install & Compatibility
Where this runs
tested against v2.6.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 1.966s · 79.5MB
glibcpy 3.10–3.95 runs
installs and imports cleanly · install 6.4s · import 1.340s · 78MB
78MB installed
● package 78MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
ndb
✓ from google.cloud import ndb
✗ from google.appengine.ext import ndb
The original App Engine NDB (`google.appengine.ext.ndb`) is distinct from this standalone client library (`google.cloud.ndb`). Using the wrong import will result in ModuleNotFoundError or unexpected behavior.
Client
✓ from google.cloud.ndb import Client
Model
✓ from google.cloud.ndb import Model
This quickstart demonstrates how to define an NDB Model, create a client, establish a context, and perform basic CRUD operations (create, read, update, delete) using `async/await`. Remember to replace 'your-gcp-project-id' with your actual Google Cloud Project ID or set the `GOOGLE_CLOUD_PROJECT` environment variable. For local development, configure `DATASTORE_EMULATOR_HOST` and ensure the Datastore emulator is running.
import os
from google.cloud import ndb
import asyncio
# For local development, point to the Datastore emulator
# Ensure you've started the emulator: `gcloud emulators datastore start`
# os.environ['DATASTORE_EMULATOR_HOST'] = 'localhost:8081'
# Replace with your actual project ID or ensure GOOGLE_CLOUD_PROJECT env var is set
project_id = os.environ.get('GOOGLE_CLOUD_PROJECT', 'your-gcp-project-id')
class User(ndb.Model):
name = ndb.StringProperty()
email = ndb.StringProperty()
created = ndb.DateTimeProperty(auto_now_add=True)
async def main():
# The NDB client is typically created once per application lifecycle
client = ndb.Client(project=project_id)
# All Datastore operations must happen within a context
async with client.context():
# Create a new user entity
user = User(name='Alice', email='alice@example.com')
user_key = await user.put()
print(f'Created user with key: {user_key.id()}')
# Fetch the user back by key
fetched_user = await user_key.get_async()
if fetched_user:
print(f'Fetched user: {fetched_user.name} ({fetched_user.email})')
# Query for users
query = User.query(User.name == 'Alice')
users_with_name = await query.fetch_async(limit=1)
if users_with_name:
print(f'Query result: {users_with_name[0].name}')
# Update a user
fetched_user.email = 'alice.new@example.com'
await fetched_user.put()
print(f'Updated user email to: {fetched_user.email}')
# Delete a user
await user_key.delete_async()
print(f'Deleted user with key: {user_key.id()}')
if __name__ == '__main__':
asyncio.run(main())
Debug
Known issues
breakingMigration from original App Engine NDB (`google.appengine.ext.ndb`) to `google-cloud-ndb` requires significant code changes. This library is a standalone client for Cloud Datastore, not a drop-in replacement for App Engine apps. Key differences include package name (`google.cloud.ndb`), mandatory `async/await` for most operations, and different client initialization and context management.fixRewrite application logic to use `google.cloud.ndb` imports, adapt to `async/await` patterns, and implement new client and context management. Consult the official migration guide if available for App Engine NDB applications.
affects: All versions of google-cloud-ndb (v2.x.x) compared to App Engine NDB (v1.x.x)
gotchaAll NDB database operations (e.g., `put()`, `get()`, `fetch()`) are asynchronous and return 'futures'. Forgetting to `await` these operations will result in the operation not being executed or incorrect data being returned (the future object itself, not its result).fixAlways use `await` before any NDB operation that interacts with the Datastore, such as `await entity.put()`, `await key.get_async()`, `await query.fetch_async()`, etc.
affects: All versions (v2.x.x)
gotchaAll Datastore interactions must occur within an NDB context. Failing to establish a context will raise a `RuntimeError: A context is required for this operation.`fixFor `async` code, use `async with client.context():`. For non-`async` code (e.g., Flask/Django request handlers), use the `@ndb.toplevel` decorator or explicitly enter/exit the context using `context = client.context(); context.__enter__(); try: ... finally: context.__exit__(None, None, None)`.
affects: All versions (v2.x.x)
gotchaThis library requires Python 3.9 or newer. It is not compatible with Python 2.7 or older Python 3 versions.fixEnsure your project's Python environment is running Python 3.9 or a newer supported version.
affects: All versions (v2.x.x)
gotchaWhen developing locally, `google-cloud-ndb` will attempt to connect to a live Datastore instance unless `DATASTORE_EMULATOR_HOST` environment variable is explicitly set to point to a running Datastore emulator. This can lead to unintended writes to your production database if not careful.fixAlways start the Datastore emulator (`gcloud emulators datastore start`) and set `os.environ['DATASTORE_EMULATOR_HOST'] = 'localhost:8081'` (or your emulator's host:port) in your local development environment before initializing the `ndb.Client`.
affects: All versions (v2.x.x)
Errors
Common errors & fixes
ContextError: No current context. NDB calls must be made in context established by google.cloud.ndb.Client.context.
NDB operations (like `put()`, `get()`, or queries) are attempted outside of an active NDB client context, which is necessary for managing caching, transactions, and binding operations to a specific Datastore client.
fixWrap NDB calls within a `with client.context():` block after initializing the NDB client.
```python
from google.cloud import ndb
client = ndb.Client()
with client.context():
# Your NDB operations here, e.g., Model.query().fetch()
class MyModel(ndb.Model):
name = ndb.StringProperty()
entity = MyModel(name='Test')
entity.put()
``` ImportError: No module named 'google.cloud' (or similar like 'ImportError: No module named google.appengine.ext.ndb')
This error typically occurs because the `google-cloud-ndb` library is not installed, or because code is trying to import from the legacy App Engine NDB path (`google.appengine.ext.ndb`) instead of the new `google.cloud.ndb` path after migrating to Python 3. It can also stem from module resolution conflicts in complex local development setups.
fixEnsure `google-cloud-ndb` is installed via pip: `pip install google-cloud-ndb`. If migrating from App Engine NDB, update import statements from `from google.appengine.ext import ndb` to `from google.cloud import ndb`. For local environment issues, verify that your Python environment (e.g., virtual environment) is correctly activated and that paths are set up to avoid conflicts.
AttributeError: 'Key' object has no attribute 'database'
This specific `AttributeError` indicates an incompatibility or incorrect usage of an `ndb.Key` object, often when working with an older or mismatched version of the `google-cloud-ndb` library, or when an object is mistakenly treated as an NDB Key. The structure and methods of `Key` objects have evolved with the library.
fixUpgrade the `google-cloud-ndb` library to the latest version: `pip install --upgrade google-cloud-ndb`. Ensure that `Key` objects are created and manipulated using the `google.cloud.ndb.Key` class and that a `google.cloud.ndb.Client` is properly initialized and its context is active when performing operations involving keys and entities.
google.auth.exceptions.DefaultCredentialsError
The application is unable to authenticate with Google Cloud because it cannot find valid credentials. This typically happens if the `GOOGLE_APPLICATION_CREDENTIALS` environment variable is not set, points to an invalid service account key file, or if the necessary Google Cloud APIs (like Cloud Datastore API) are not enabled for the project.
fixProvide valid Google Cloud credentials by setting the `GOOGLE_APPLICATION_CREDENTIALS` environment variable to the file path of your service account JSON key. For example:
`export GOOGLE_APPLICATION_CREDENTIALS="/path/to/your-service-account-key.json"` (Linux/macOS) or `set GOOGLE_APPLICATION_CREDENTIALS=C:\path\to\your-service-account-key.json` (Windows). Also, ensure 'Cloud Datastore API' and 'Google Cloud Firestore API' are enabled in your Google Cloud project's API & Services dashboard.
no matching index found. recommended index is:
A query is being executed that requires a custom index which has not been defined in your `index.yaml` file or deployed to your Google Cloud project. Datastore queries often need pre-built indexes for efficient execution, especially for queries involving multiple filters, inequality filters, or sorting on multiple properties.
fixWhen running on the local development server, the server will suggest the required index in the error message. Copy the recommended index definition into your `index.yaml` file. Then, deploy the updated indexes to your Google Cloud project using the `gcloud datastore indexes create path/to/index.yaml` command.
Upgrade
Version history
2.6.0latest on PyPI · released Aug 24, 2026
Audit
Dependencies
google-cloud-datastorerequiredCore client library for interacting with Google Cloud Datastore.