Refs #33646 -- Added example for async cross-thread connection access.

This commit is contained in:
Carlton Gibson 2022-04-20 11:56:11 +02:00
parent 5dfa6fca96
commit 6b53114dd8
1 changed files with 26 additions and 0 deletions

View File

@ -279,3 +279,29 @@ thread and thus is fully compatible with async mode. Note that sync code will
always be in a *different* thread to any async code that is calling it, so you always be in a *different* thread to any async code that is calling it, so you
should avoid passing raw database handles or other thread-sensitive references should avoid passing raw database handles or other thread-sensitive references
around. around.
In practice this restriction means that you should not pass features of the
database ``connection`` object when calling ``sync_to_async()``. Doing so will
trigger the thread safety checks:
.. code-block:: pycon
# DJANGO_SETTINGS_MODULE=settings.py python -m asyncio
>>> import asyncio
>>> from asgiref.sync import sync_to_async
>>> from django.db import connection
>>> # In an async context so you cannot use the database directly:
>>> connection.cursor()
...
django.core.exceptions.SynchronousOnlyOperation: You cannot call this from
an async context - use a thread or sync_to_async.
>>> # Nor can you pass resolved connection attributes across threads:
>>> await sync_to_async(connection.cursor)()
...
django.db.utils.DatabaseError: DatabaseWrapper objects created in a thread
can only be used in that same thread. The object with alias 'default' was
created in thread id 4371465600 and this is thread id 6131478528.
Rather, you should encapsulate all database access within a helper function
that can be called with ``sync_to_async()`` without relying on the connection
object in the calling code.