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?