Stay organized with collections Save and categorize content based on your preferences.
Note: Developers building new applications are strongly encouraged to use the NDB Client Library, which has several benefits compared to this client library, such as automatic entity caching via the Memcache API. If you are currently using the older DB Client Library, read the DB to NDB Migration Guide
The Async Datastore API allows you to make parallel, non-blocking calls to the datastore and to retrieve the results of these calls at a later point in the handling of the request. This documentation describes the following aspects of the Async Datastore API:
Working with the Async Datastore ServiceWith the async datastore API, you make datastore calls using methods of the form *_async
(such as get_async() in the google.appengine.ext.db
package). The following code sample demonstrates some simple datastore operations using the asynchronous methods:
from google.appengine.ext import db get_future = db.get_async(key) put_future = db.put_async(model) delete_future = db.delete_async(key) allocate_ids_future = db.allocate_ids_async(key, 10)
These functions perform the same operations as the synchronous versions, except they immediately return an asynchronous object that you can use to get the real result at some later point. The following code sample demonstrates how to get the asynchronous result using get_result():
entity = get_future.get_result() key = put_future.get_result() range = allocate_ids_future.get_result() # Wait for the operation to complete without returning a value. # Exceptions that occurred in the call are thrown here. Calling # get_result() allows you to verify that the deletion succeeded. delete_future.get_result()
Note: Exceptions are not thrown until you call get_result(). Calling this method allows you to verify that the async operation succeeded.
Working with Async TransactionsAsync datastore API calls can participate in transactions just like synchronous calls. Here's a function that adjusts the salary of an Employee
and writes an additional SalaryAdjustment
entity in the same entity group as the Employee
, all within a single transaction.
def adjust_salary(employee_key, raise_ammount): def runner(): # Async call to lookup the Employee entity employee_entity_future = db.get_async(employee_key) # Create and put a SalaryAdjustment entity in parallel with the lookup adjustment_entity = SalaryAdjustment(parent=employeeKey) adjustment_entity.adjustment = raise_amount db.put_async(adjustmentEntity) # Fetch the result of our lookup to make the salary adjustment employee_entity = employee_entity_future.get_result() employee_entity.salary += raise_amount # Re-put the Employee entity with the adjusted salary. db.put_async(employee_entity) db.run_in_transaction(runner)
This sample illustrates an important difference between async calls with no transactions and async calls within transactions. When you are not using a transaction, the only way to ensure that an individual async call has completed is to fetch the result of the async object using a transaction. Committing that transaction blocks on the result of all async calls made within a transaction.
So, in our example above, even though our async call to insert the SalaryAdjustment
entity may still be outstanding when runner()
finishes, the commit will not happen until the insert completes.
We do not currently expose an explicitly async API for queries. However, when you invoke Query.run(), the query immediately returns and asynchronously prefetches results. This allows your application to perform work in parallel while query results are fetched.
# ... q1 = Salesperson.all().filter('date_of_hire <', one_month_ago) # Returns instantly, query is executing in the background. recent_hires = q1.run() q2 = Customer.all().filter('last_contact >', one_year_ago) # Also returns instantly, query is executing in the background. needs_followup = q2.run() schedule_phone_call(recent_hires, needs_followUp)
Unfortunately, Query.fetch() does not have the same behavior.
When To Use Async Datastore CallsWhen you call a synchronous google.ext.db
method, such as db.get(), your code blocks until the call to the datastore completes. If the only thing your application needs to do is render the result of the get() in HTML, blocking until the call is complete is a perfectly reasonable thing to do. However, if your application needs the result of the get() plus the result of a Query to render the response—and if the get() and the Query don't have any data dependencies—then waiting until the get() completes to initiate the Query is a waste of time. Here is an example of some code that can be improved by using the async API:
# Read employee data from the Datastore employee = Employee.get_by_key_name('Max') # Blocking for no good reason! # Fetch payment history query = PaymentHistory.all().ancestor(employee.key()) history = query.fetch(10) render_html(employee, history)
Instead of waiting for the get() to complete, use db.get_async() to execute the call asynchronously:
employee_key = db.Key.from_path(Employee.kind(), 'Max') # Read employee data from the Datastore employee_future = db.get_async(employee_key) # Returns immediately! # Fetch payment history query = PaymentHistory.all().ancestor(employee_key) # Implicitly performs query asynchronously history_itr = query.run(config=datastore_query.QueryOptions(limit=10)) employee = employee_future.get_result() render_html(employee, history_itr)
The synchronous and asynchronous versions of this code use similar amounts of CPU (after all, they both perform the same amount of work), but since the asynchronous version allows the two datastore operations to execute in parallel, the asynchronous version has lower latency. In general, if you need to perform multiple datastore operations that don't have any data dependencies, the asynchronous API can significantly improve latency.
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-08-07 UTC.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Hard to understand","hardToUnderstand","thumb-down"],["Incorrect information or sample code","incorrectInformationOrSampleCode","thumb-down"],["Missing the information/samples I need","missingTheInformationSamplesINeed","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-08-07 UTC."],[[["Developers should prioritize the NDB Client Library over the older DB Client Library for new applications due to benefits like automatic entity caching."],["The Async Datastore API enables parallel, non-blocking calls to the datastore, using methods like `*_async` (e.g., `get_async()`, `put_async()`), which return asynchronous objects to retrieve results later."],["Async datastore calls can be used within transactions, and transaction commits will block until all async calls within that transaction have completed."],["Queries using `Query.run()` return immediately and asynchronously prefetch results, allowing parallel work, unlike `Query.fetch()`."],["Using the asynchronous API for multiple, independent datastore operations can significantly reduce latency by allowing parallel execution compared to sequential synchronous calls."]]],[]]
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4