Async Django ORM (Django Async Backend)
Async Django ORM and PostgreSQL database backend.
Installation
pip install django-async-backend[binary]
The binary extra installs the C-accelerated psycopg implementation. Without
it you get the pure-Python implementation, which is noticeably slower. If you
use connection pooling, add the pool extra as well:
pip install django-async-backend[binary,pool]
The package tracks Django's major and minor version โ for example 6.0.x
matches Django 6.0 โ because a large part of the ORM layer is generated from
Django's own source.
Quick start
# settings.py
DATABASES = {
"default": {
"ENGINE": "django_async_backend.db.backends.postgresql",
...
},
}
INSTALLED_APPS = [
...
"django_async_backend",
]
from django.db import models
from django_async_backend.db import async_connections
from django_async_backend.db.models.base import AsyncModelMixin
from django_async_backend.db.transaction import async_atomic
class Book(AsyncModelMixin, models.Model):
name = models.CharField(max_length=100)
async def notify(book_id: int) -> None:
...
async def main() -> None:
connection = async_connections["default"]
async with async_atomic():
book = await Book.async_objects.acreate(name="Django")
# async callbacks are supported; runs only if the transaction commits
await connection.on_commit(lambda: notify(book.pk))
book.name = "Django Async"
await book.async_save(update_fields=["name"])
async with async_atomic(): # savepoint
await Book.async_objects.filter(name="draft").adelete()
print(await Book.async_objects.acount())
async for row in Book.async_objects.order_by("name"):
print(row.pk, row.name)
Or drop to a raw async cursor:
async with await connection.cursor() as cursor:
await cursor.execute("SELECT id, name FROM app_book ORDER BY name")
print(cursor.rowcount)
async for row in cursor:
print(row)
[!WARNING] Async does not mean parallel. A task gets one connection per database alias, and every ORM and cursor call in that task takes turns on it โ so awaiting several queries in a row does not make them run concurrently.
The connection is owned by the task that created it, so you cannot fan out onto it either: using it from another task โ
asyncio.create_task(),asyncio.gather(),asyncio.TaskGroupโ raisesRuntimeError. Wrapping the fan-out in a singleasync_atomic()block does not make it safe. To run queries in parallel, give each task its own connection withasync_new_connectionโ sparingly, since each call opens a real connection and a wide fan-out can exhaust the server's limit.
Supported methods
Legend: โ supported ยท โ not supported ยท โ ๏ธ supported with caveats
QuerySet methods
| methods | supported | comments |
|---|---|---|
Model.objects.aget |
โ | |
Model.objects.acreate |
โ | |
Model.objects.acount |
โ | |
Model.objects.none |
โ | |
Model.objects.abulk_create |
โ | |
Model.objects.abulk_update |
โ | |
Model.objects.aget_or_create |
โ | |
Model.objects.aupdate_or_create |
โ | |
Model.objects.aearliest |
โ | |
Model.objects.alatest |
โ | |
Model.objects.afirst |
โ | |
Model.objects.alast |
โ | |
Model.objects.ain_bulk |
โ | |
Model.objects.adelete |
โ | |
Model.objects.aupdate |
โ | |
Model.objects.aexists |
โ | |
Model.objects.acontains |
โ | |
Model.objects.aexplain |
โ | |
Model.objects.araw |
โ | |
Model.objects.all |
โ | |
Model.objects.filter |
โ | |
Model.objects.exclude |
โ | |
Model.objects.complex_filter |
โ | |
Model.objects.union |
โ | |
Model.objects.intersection |
โ | |
Model.objects.difference |
โ | |
Model.objects.select_related |
โ | |
Model.objects.select_for_update |
โ | |
Model.objects.prefetch_related |
โ | |
Model.objects.aaggregate |
โ | |
Model.objects.annotate |
โ | |
Model.objects.order_by |
โ | |
Model.objects.distinct |
โ | |
Model.objects.extra |
โ | |
Model.objects.reverse |
โ | |
Model.objects.defer |
โ ๏ธ | not safe for async, will not be implemented โ use values/values_list |
Model.objects.only |
โ ๏ธ | not safe for async, will not be implemented โ use values/values_list |
Model.objects.using |
โ | |
Model.objects.resolve_expression |
โ | |
Model.objects.ordered |
โ | |
Model.objects.values |
โ | |
Model.objects.values_list |
โ | |
Model.objects.dates |
โ | |
Model.objects.datetimes |
โ | |
Model.objects.alias |
โ | |
Model.objects.aiterator |
โ |
Dunder methods
| methods | supported | comments |
|---|---|---|
__aiter__ |
โ | |
__iter__ |
โ ๏ธ | raises TypeError โ use async for obj in qs |
__len__ |
โ ๏ธ | raises TypeError โ use await qs.acount() |
__contains__ |
โ ๏ธ | falls back to __iter__, so it raises TypeError too |
__bool__ |
โ ๏ธ | truth-testing falls back to __len__, so if qs: raises TypeError โ use await qs.aexists() |
__repr__ |
โ | |
__and__ |
โ | |
__or__ |
โ | |
__xor__ |
โ | |
__getitem__ |
โ |
Model methods
| methods | supported | comments |
|---|---|---|
Model.asave |
โ | async_save |
Model.adelete |
โ | async_delete |
Model.arefresh_from_db |
โ |
RawQuerySet
Not supported โ
Related managers
Not supported โ โ instance.<related>.all() is the sync ORM. See
Pitfalls.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file django_async_backend-6.1.2.tar.gz.
File metadata
- Download URL: django_async_backend-6.1.2.tar.gz
- Upload date:
- Size: 119.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
poetry/2.1.1 CPython/3.12.14 Linux/6.17.0-1022-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b781ec4d9e28c46c2dca9422ae820a6d8763b6a29922ccb5a04db7204172bbcc
|
|
| MD5 |
8b77f738c04e7a9e9f1b46020d8b6cd7
|
|
| BLAKE2b-256 |
51e6b95d8fdaa9aa4d92620e34fec7d80e269a947c91ba6e0f7a33238c8ea85f
|
File details
Details for the file django_async_backend-6.1.2-py3-none-any.whl.
File metadata
- Download URL: django_async_backend-6.1.2-py3-none-any.whl
- Upload date:
- Size: 129.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
poetry/2.1.1 CPython/3.12.14 Linux/6.17.0-1022-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
defb33ebad4ddbdf7686b26b75b1a8ab06c179d24c815ce5ad3979d994126087
|
|
| MD5 |
089dcee4fbf9b3fca920aea070be5221
|
|
| BLAKE2b-256 |
52941d73e2109ec49edc475ccc916c7592f4ebd5443078456a19a4f03297c249
|