如何在异步函数中从django orm获取数据?

jaql4c8m  于 2022-12-05  发布在  Go
关注(0)|答案(2)|浏览(150)

我需要在一个异步函数中从数据库中检索数据。如果我只检索一个对象,例如:

users = await sync_to_async(Creators.objects.first)()

一切正常。2但是如果响应包含多个对象,我会得到一个错误。

@sync_to_async
def get_creators():
    return Creators.objects.all()

async def CreateBotAll():
    users = await get_creators()

    for user in users:
        print(user)

追踪:

Traceback (most recent call last):
File "/home/django/django_venv/lib/python3.8/site- 
packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/home/django/django_venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 
181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/django/django_venv/src/reseller/views.py", line 29, in test
asyncio.run(TgAssistant.CreateBotAll())
File "/usr/lib/python3.8/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
return future.result()
File "/home/django/django_venv/src/reseller/TgAssistant.py", line 84, in CreateBotAll
for user in users:
File "/home/django/django_venv/lib/python3.8/site-packages/django/db/models/query.py", line 
280, in __iter__
self._fetch_all()
File "/home/django/django_venv/lib/python3.8/site-packages/django/db/models/query.py", line 
1324, in _fetch_all
self._result_cache = list(self._iterable_class(self))
File "/home/django/django_venv/lib/python3.8/site-packages/django/db/models/query.py", line 
51, in __iter__
results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
File "/home/django/django_venv/lib/python3.8/site-packages/django/db/models/sql/compiler.py", 
line 1173, in execute_sql
cursor = self.connection.cursor()
File "/home/django/django_venv/lib/python3.8/site-packages/django/utils/asyncio.py", line 31, 
in inner
raise SynchronousOnlyOperation(message)
django.core.exceptions.SynchronousOnlyOperation: You cannot call this from an async context - 
use a thread or sync_to_async.

我是这样做的:

@sync_to_async
def get_creators():
    sql = Creators.objects.all()
    x = [creator for creator in sql]
    return x

难道没有更优雅的解决方案吗?

l5tcr1uw

l5tcr1uw1#

您可以尝试将get_creators响应 Package 到列表中:

@sync_to_async
def get_creators():
    return list(Creators.objects.all())
tvokkenx

tvokkenx2#

从Django 4.1开始,您可以执行以下操作:

async for creator in Creators.objects.all():
    print(creator)

只要表达式不会导致对查询进行求值,就可以用filter等来替换它。
也有get、delete等的异步版本,前面加上'a',所以您的

users = await sync_to_async(Creators.objects.first)()

可替换为:

user = await Creators.object.afirst()

相关问题