浏览代码

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

Carlton Gibson 2 年之前
父节点
当前提交
6b53114dd8
共有 1 个文件被更改,包括 26 次插入0 次删除
  1. 26 0
      docs/topics/async.txt

+ 26 - 0
docs/topics/async.txt

@@ -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
 should avoid passing raw database handles or other thread-sensitive references
 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.