Почему мне нужно создавать новый поток для обновления записи базы данных? (Рамка отдыха Джанго)Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Почему мне нужно создавать новый поток для обновления записи базы данных? (Рамка отдыха Джанго)

Сообщение Anonymous »

Для создания API я использую Django Rest Framework.
Идея состоит в том, что пользователь загружает некоторые данные с помощью запроса POST. Эти данные загружаются в базу данных. После загрузки создается новый поток Python, выполняющий некоторые операции с указанными данными. Затем, когда операции завершаются, результат записывается в исходную запись базы данных.
При таком подходе API остается доступным, при этом операции выполняются в фоновом режиме. Пользователь может проверить статус операции с помощью GET-запроса.
По какой-то причине при попытке обновить запись с результатами операции я получил следующую ошибку:
SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async
Это сбивало с толку, поскольку функция работы и обновления уже выполнялась с использованием потока.
Я не получал ошибку, когда заменяя операции некоторыми простыми результатами макетного теста (строками). Даже при использовании time.sleep() в течение более длительного периода, чем потребовались бы фактические операции. Поэтому я подозреваю, что проблема как-то связана с выполняемыми мной операциями, хотя они вообще не взаимодействуют с Django.
Я решил проблему, создав новые потоки специально для сохранения обновленные данные в базе данных. Но мне все еще интересно: зачем это нужно?
@api_view(['POST'])
def create_job(request):
serializer = JobsSerializer(data=request.data)
if serializer.is_valid():
job = serializer.save()
job_thread = threading.Thread(target=trigger_operation, args=(job,)).start()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

def trigger_operation(db_record):
db_record.status = Jobs.Status.WORKING
threading.Thread(target=db_record.save, args=()).start()

try:
results = actual_operation(db_record.url)
status = Jobs.Status.DONE
except Exception as e:
results = e
status = Jobs.Status.FAILED
finally:
db_record.status = status
db_record.results = results
threading.Thread(target=db_record.save, args=()).start()


Подробнее здесь: https://stackoverflow.com/questions/793 ... django-res
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»