Skip to main content

Async Django ORM (Django Async Backend)

CI status Latest Version in PyPI Supported Python versions

Monthly downloads

Async Django ORM and PostgreSQL database backend.

Django's a-prefixed ORM methods (aget, acreate, …) are thin sync_to_async wrappers: the query still runs on a threadpool, on a synchronous connection. django-async-backend replaces the database layer itself, so queries are issued on a real asyncio connection through psycopg 3, with async transactions, async cursors and optional connection pooling — no thread emulation.

The project is production ready: the API is stable, and each release is pinned to the Django feature release it was generated against, so upgrades stay predictable.

📖 Read the documentation


Compatibility

The package tracks Django's major and minor version, so the release you install is pinned to the Django feature release it was generated against.

django-async-backend Django
6.1.3 6.1.0

Part of the ORM layer is generated from Django's own source, so a Django feature release gets a matching django-async-backend feature release rather than a loosened version range. Patch releases within a line are ordinary bugfix releases and are safe to upgrade to.

[!IMPORTANT] Run this under ASGI. django-async-backend is developed for ASGI, and that is the only mode it is supported in. Under WSGI — including the Django development server — it behaves inconsistently, because WSGI creates a new event loop for each request and the async connection state cannot be managed reliably across them. Connection pooling in particular is not supported there.

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 first used it, so you cannot fan out onto it either: using it from another task — asyncio.create_task(), asyncio.gather(), asyncio.TaskGroup — raises RuntimeError. Wrapping the fan-out in a single async_atomic() block does not make it safe. To run queries in parallel, give each task its own connection with async_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.

Metadata

Release files for django-async-backend 6.1.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-async-backend 6.1.5
File Size Uploaded
django_async_backend-6.1.5.tar.gz 108.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-async-backend 6.1.5
File Interpreter ABI Platform
django_async_backend-6.1.5-py3-none-any.whl Python 3 none any Details

Total release size: 225.3 kB

Release files / django_async_backend-6.1.5.tar.gz

Download URL django_async_backend-6.1.5.tar.gz
Size 108.2 kB
Tags Source
SHA-256 checksum
How to use checksums
b9fe974e86e7cbe5df651d591da5c2f6cea66a81a30920157c4cb7be58dce3d8
BLAKE2b-256 checksum
How to use checksums
81a43382955410e8b0bcbefbf262d1ad000227f294c0932ea75bd76eca6e4bcb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.1.1 CPython/3.12.14 Linux/6.17.0-1022-azure

Release files / django_async_backend-6.1.5-py3-none-any.whl

Download URL django_async_backend-6.1.5-py3-none-any.whl
Size 117.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ce5280ea4a79c6184c91d62772a54a528c9f8f9c1783146fa8c990aca195d3ea
BLAKE2b-256 checksum
How to use checksums
df9d52b37053c905d190ba5a6fd475b4cc0dbf3f1e67f8664fa09da161c1e6da
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.1.1 CPython/3.12.14 Linux/6.17.0-1022-azure

Release history Release notifications | RSS feed

This release

6.1.5 This release

2 release files

6.1.4

2 release files

6.1.3

2 release files

6.1.2

2 release files

6.1.1

2 release files

6.1.0

2 release files

6.0.9

2 release files

6.0.8

2 release files

6.0.7

2 release files

6.0.6

2 release files

6.0.5

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page