Mur*_*nio 5 django asynchronous python-asyncio
我正在编写一个命令来在数据库中随机创建 500 万个订单。
def constrained_sum_sample(
number_of_integers: int, total: Optional[int] = 5000000
) -> int:
"""Return a randomly chosen list of n positive integers summing to total.
Args:
number_of_integers (int): The number of integers;
total (Optional[int]): The total sum. Defaults to 5000000.
Yields:
(int): The integers whose the sum is equals to total.
"""
dividers = sorted(sample(range(1, total), number_of_integers - 1))
for i, j in zip(dividers + [total], [0] + dividers):
yield i - j
def create_orders():
customers = Customer.objects.all()
number_of_customers = Customer.objects.count()
for customer, number_of_orders in zip(
customers,
constrained_sum_sample(number_of_integers=number_of_customers),
):
for _ in range(number_of_orders):
create_order(customer=customer)
Run Code Online (Sandbox Code Playgroud)
number_of_customers将至少大于 1k 并且该create_order函数执行至少 5 次 db 操作(一个创建订单,一个随机获取订单的商店,一个创建订单项(最多可以达到 30 个,也是随机的),一个用于获取该项目的产品(或更高但等于该项目),另一个用于创建销售说明。
正如您可能怀疑这需要很长时间才能完成。我曾尝试异步执行这些操作,但未成功。我的所有尝试(至少有十多次;其中大多数使用sync_to_async)都引发了以下错误:
SynchronousOnlyOperation you cannot call this from an async context - use a thread or sync_to_async
Run Code Online (Sandbox Code Playgroud)
在我继续破头之前,我问:有可能实现我的愿望吗?如果是这样,我应该如何进行?
非常感谢!
Django 3.1 正式对视图和中间件提供异步支持,但是如果您尝试在异步函数中调用 ORM,您将得到 SynchronousOnlyOperation。
如果您需要从异步函数调用数据库,他们提供了帮助程序实用程序,例如:async_to_sync和sync_to_async以在线程或协程模式之间进行更改,如下所示:
from asgiref.sync import sync_to_async
results = await sync_to_async(Blog.objects.get, thread_sensitive=True)(pk=123)
Run Code Online (Sandbox Code Playgroud)
#settings.py
DJANGO_ALLOW_ASYNC_UNSAFE=True
Run Code Online (Sandbox Code Playgroud)
Django 中需要这样做的原因是许多库,特别是数据库适配器,要求在创建它们的同一线程中访问它们。此外,许多现有的 Django 代码假设它们都在同一线程中运行,例如中间件添加事物到请求以便稍后在视图中使用。
发行说明中有更多有趣的消息: https://docs.djangoproject.com/en/3.1/topics/async/
| 归档时间: |
|
| 查看次数: |
1070 次 |
| 最近记录: |