I’ve took a first pass at adding async-native support to the ORM.
No surprises, it’s going to be a big change in terms of code review, so I think we should break it into smaller phases. Ideally each of them would be a Pull Request and they could be delivered across multiple releases of Django.
Phase1: connection-level API
This would cover the new new_connection
context managers, and provide an async cursor that the user could use.
The goal of this first phase is to give users a low-level async cursor that they can use for raw SQL query:
from django.db import new_connection
async def my_view(request):
async with new_connection() as conn:
async with conn.acursor() as cursor:
await cursor.execute("SELECT * FROM my_table")
result = await cursor.fetchone()
The scope will also include manual transaction management, such as acommit
and arollback
. transaction.atomic
would be out of scope.
Phase 2: transaction.atomic
This would build on the previous work to provide an async-compatiable transaction.atomic
decorator:
from django.db import new_connection, transaction
async def my_view(request):
async with new_connection() as conn:
async with transaction.atomic():
async with conn.acursor() as cursor:
await cursor.execute("SELECT * FROM my_table")
result = await cursor.fetchone()
All methods in django.db.transaction
would be in scope: acommit()
, arollback()
, asavepoint()
, asavepoint_commit()
, asavepoint_rollback()
, etc.
Phase 3: Models and managers, django.contrib
apps
In this phase we’ll coonvert manager methods from the current “faux-async” to be async-native. This will also include model methods such as .asave()
and adelete()
, the Delete collector.
We’ll also convert models in django.contrib
that already have faux-async methods, such as contrib.auth
and contrib.sessions
. We will not be adding async APIs to any contrib apps that do not yet have them.
Does it sounds like a good plan? Comments, Questions, Concerns?