The much-awaited pull request for an async-compatible interface to Queryset just got merged into the main branch of Django.
Pull Request - https://github.com/django/django/pull/14843
The Django core team has been progressively adding async support to the framework. Asynchronous views and middlewares were part of the Django 3.1 release and with the latest changes now Django ORM will be able to run async ORM queries with some exceptions.
With the upcoming release of Django you no longer have to wrap queries in sync_to_async
as such
results = await sync_to_async(Blog.objects.get, thread_sensitive=True)(pk=123)
Now you can write async queries like this,
results = await Blog.objects.aget(pk=123)
Note that, at this stage, the underlying database operations remain synchronous, with contributions ongoing to push asynchronous support down into the SQL compiler, and integrate asynchronous database drivers. The new asynchronous queryset interface currently encapsulates the necessary ``sync_to_async()`` operations for you, and will allow your code to take advantage of developments in the ORM's asynchronous support as it evolves.
Django 4.1 is expected to release in August 2022, the release notes [ UNDER DEVELOPMENT ] can be found here - https://docs.djangoproject.com/en/dev/releases/4.1/
From the development docs:
Asynchronous ORM interface
--------------------------
``QuerySet`` now provides an asynchronous interface for all data access
operations. These are named as-per the existing synchronous operations but with
an ``a`` prefix, for example ``acreate()``, ``aget()``, and so on.
The new interface allows you to write asynchronous code without needing to wrap
ORM operations in ``sync_to_async()``::
async for author in Author.objects.filter(name__startswith="A"):
book = await author.books.afirst()
Note that, at this stage, the underlying database operations remain
synchronous, with contributions ongoing to push asynchronous support down into
the SQL compiler, and integrate asynchronous database drivers. The new
asynchronous queryset interface currently encapsulates the necessary
``sync_to_async()`` operations for you, and will allow your code to take
advantage of developments in the ORM's asynchronous support as it evolves.
------------------------------------------------------------------------------
Queries & the ORM
-----------------
.. versionadded:: 4.1
With some exceptions, Django can run ORM queries asynchronously as well::
async for author in Author.objects.filter(name__startswith="A"):
book = await author.books.afirst()
Detailed notes can be found in :ref:`async-queries`, but in short:
* All ``QuerySet`` methods that cause a SQL query to occur have an
``a``-prefixed asynchronous variant.
* ``async for`` is supported on all QuerySets (including the output of
``values()`` and ``values_list()``.)
Transactions do not yet work in async mode. If you have a piece of code that
needs transactions behaviour, we recommend you write that piece as a single
synchronous function and call it using :func:`sync_to_async`.
Not so long ago a discussion on the naming convention for async variants took place on the official Django forum where the core members voted in favour of variants with "a" prefix.
In the same PR, Andrew mentioned that it will take a while before we can use async compatible drivers such as Psycopg3.
Nevertheless it's still a big win for the Django community. The ORM is undoubtedly one of the most complex parts of Django and now it is capable of running async queries with the new QuerySet APIs without any major breaking backwards-incompatible changes!
Finally a big thanks to Andrew, Mariusz, Adam, Carlton and all the contributors of Django for the awesome work they have been doing for Django.