{"id":4958,"library":"google-cloud-ndb","title":"NDB Library for Google Cloud Datastore","description":"google-cloud-ndb is a Python client library for Google Cloud Datastore, providing an ORM-like interface for interacting with the service. It is a modern, standalone re-implementation of the original App Engine NDB. The current version is 2.4.2, and it is part of the larger `google-cloud-python` monorepo, which has frequent releases, though individual library updates may be less frequent.","status":"active","version":"2.4.2","language":"en","source_language":"en","source_url":"https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-ndb","tags":["google cloud","datastore","ndb","orm","nosql","asyncio"],"install":[{"cmd":"pip install google-cloud-ndb","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Core client library for interacting with Google Cloud Datastore.","package":"google-cloud-datastore"}],"imports":[{"note":"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.","wrong":"from google.appengine.ext import ndb","symbol":"ndb","correct":"from google.cloud import ndb"},{"symbol":"Client","correct":"from google.cloud.ndb import Client"},{"symbol":"Model","correct":"from google.cloud.ndb import Model"}],"quickstart":{"code":"import os\nfrom google.cloud import ndb\nimport asyncio\n\n# For local development, point to the Datastore emulator\n# Ensure you've started the emulator: `gcloud emulators datastore start`\n# os.environ['DATASTORE_EMULATOR_HOST'] = 'localhost:8081'\n\n# Replace with your actual project ID or ensure GOOGLE_CLOUD_PROJECT env var is set\nproject_id = os.environ.get('GOOGLE_CLOUD_PROJECT', 'your-gcp-project-id') \n\nclass User(ndb.Model):\n    name = ndb.StringProperty()\n    email = ndb.StringProperty()\n    created = ndb.DateTimeProperty(auto_now_add=True)\n\nasync def main():\n    # The NDB client is typically created once per application lifecycle\n    client = ndb.Client(project=project_id)\n\n    # All Datastore operations must happen within a context\n    async with client.context():\n        # Create a new user entity\n        user = User(name='Alice', email='alice@example.com')\n        user_key = await user.put()\n        print(f'Created user with key: {user_key.id()}')\n\n        # Fetch the user back by key\n        fetched_user = await user_key.get_async()\n        if fetched_user:\n            print(f'Fetched user: {fetched_user.name} ({fetched_user.email})')\n        \n        # Query for users\n        query = User.query(User.name == 'Alice')\n        users_with_name = await query.fetch_async(limit=1)\n        if users_with_name:\n            print(f'Query result: {users_with_name[0].name}')\n\n        # Update a user\n        fetched_user.email = 'alice.new@example.com'\n        await fetched_user.put()\n        print(f'Updated user email to: {fetched_user.email}')\n\n        # Delete a user\n        await user_key.delete_async()\n        print(f'Deleted user with key: {user_key.id()}')\n\nif __name__ == '__main__':\n    asyncio.run(main())\n","lang":"python","description":"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."},"warnings":[{"fix":"Rewrite 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.","message":"Migration 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.","severity":"breaking","affected_versions":"All versions of google-cloud-ndb (v2.x.x) compared to App Engine NDB (v1.x.x)"},{"fix":"Always 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.","message":"All 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).","severity":"gotcha","affected_versions":"All versions (v2.x.x)"},{"fix":"For `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)`.","message":"All Datastore interactions must occur within an NDB context. Failing to establish a context will raise a `RuntimeError: A context is required for this operation.`","severity":"gotcha","affected_versions":"All versions (v2.x.x)"},{"fix":"Ensure your project's Python environment is running Python 3.9 or a newer supported version.","message":"This library requires Python 3.9 or newer. It is not compatible with Python 2.7 or older Python 3 versions.","severity":"gotcha","affected_versions":"All versions (v2.x.x)"},{"fix":"Always 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`.","message":"When 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.","severity":"gotcha","affected_versions":"All versions (v2.x.x)"}],"env_vars":null,"last_verified":"2026-04-12T00:00:00.000Z","next_check":"2026-07-11T00:00:00.000Z"}