Запрос к Django ORM внутри задачи celery: SynchronousOnlyOperation: Вы не можете вызвать это из асинхронного контекста - используйте поток или sync_to_async

Мы используем задания celery вместе с Django, и в разных заданиях celery есть несколько случаев, когда задание celery читает и пишет в базу данных через ORM Django.

Каждый раз при использовании ORM внутри задачи celery, задачи бросает:

SynchronousOnlyOperation: Вы не можете вызвать это из асинхронного контекста - используйте поток или sync_to_async.

Мне кажется странным, что это происходит иногда, а не каждый раз, когда запрос выполняется через ORM? Во-вторых, при попытке решить эту проблему в соответствии с предложениями в документации Django здесь:

https://docs.djangoproject.com/en/3.2/topics/async/

примерно так: Пример sync_to_asynch ussage

Я столкнулся с другой проблемой: TypeError: 'coroutine' object is not iterable

Мой вопрос:

  1. Why does this issue only occurs every once in a while and not everytime I query using the ORM inside the celery task?

  2. Is there a way it can be solved?

Окружение

Задачи celery запускаются с помощью gevent следующим образом: celery -A Tasks worker -P gevent -c 10 -l INFO -E

Python 3.8

Django 3.1.4

Celery 5.1.0

sync_to_async() вернет корутину. Как намекает ошибка типа TypeError, вы не можете выполнять итерацию над coroutine напрямую. Вы должны await его, как показано в примере.

Из документации:

from asgiref.sync import sync_to_async

results = await sync_to_async(Blog.objects.get, thread_sensitive=True)(pk=123)

На вашей фотографии вы не await звоните.

Вернуться на верх