I need to retrieve data from the database inside an asynchronous function. If I retrieve only one object by executing e.g:
users = await sync_to_async(Creators.objects.first)()
everything works as it should. But if the response contains multiple objects, I get an error.
@sync_to_asyncdef get_creators(): return Creators.objects.all()async def CreateBotAll(): users = await get_creators() for user in users: print(user)
Tracing:
Traceback (most recent call last):File "/home/django/django_venv/lib/python3.8/site- packages/django/core/handlers/exception.py", line 47, in innerresponse = get_response(request)File "/home/django/django_venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_responseresponse = wrapped_callback(request, *callback_args, **callback_kwargs)File "/home/django/django_venv/src/reseller/views.py", line 29, in testasyncio.run(TgAssistant.CreateBotAll())File "/usr/lib/python3.8/asyncio/runners.py", line 44, in runreturn loop.run_until_complete(main)File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_completereturn future.result()File "/home/django/django_venv/src/reseller/TgAssistant.py", line 84, in CreateBotAllfor 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_allself._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_sqlcursor = self.connection.cursor()File "/home/django/django_venv/lib/python3.8/site-packages/django/utils/asyncio.py", line 31, in innerraise SynchronousOnlyOperation(message)django.core.exceptions.SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async.
I made it work that way:
@sync_to_asyncdef get_creators(): sql = Creators.objects.all() x = [creator for creator in sql] return x
Isn't there a more elegant solution?