Warum muss ich einen neuen Thread erstellen, um einen Datenbankeintrag zu aktualisieren? (Django Rest Framework)Python

Python-Programme
Guest
 Warum muss ich einen neuen Thread erstellen, um einen Datenbankeintrag zu aktualisieren? (Django Rest Framework)

Post by Guest »

Ich verwende Django Rest Framework zum Erstellen einer API.
Die Idee ist, dass der Benutzer einige Daten mithilfe einer POST-Anfrage hochlädt. Diese Daten werden in eine Datenbank hochgeladen. Nach dem Hochladen wird ein neuer Python-Thread erstellt, der einige Vorgänge für die Daten ausführt. Wenn die Vorgänge dann abgeschlossen sind, wird das Ergebnis in den ursprünglichen Datenbankdatensatz geschrieben.
Mit diesem Ansatz bleibt die API zugänglich, während gleichzeitig die Vorgänge im Hintergrund bearbeitet werden. Der Benutzer kann den Vorgangsstatus mithilfe einer GET-Anfrage überprüfen.
Aus irgendeinem Grund wurde beim Versuch, den Datensatz mit den Vorgangsergebnissen zu aktualisieren, die folgende Fehlermeldung angezeigt:

Code: Select all

SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async
Es war verwirrend, da die Betriebs- und Aktualisierungsfunktion bereits über einen Thread ausgeführt wurde.
Ich würde den Fehler nicht erhalten, wenn Ersetzen der Operationen durch einige einfache Modelltestergebnisse (Strings). Auch nicht, wenn time.sleep() für einen längeren Zeitraum verwendet wird, als die tatsächlichen Vorgänge dauern würden. Daher vermute ich, dass das Problem etwas mit den von mir ausgeführten Vorgängen zu tun hat, auch wenn diese überhaupt nicht mit Django interagieren.
Die fehlerhaften Zeilen werden auskommentiert und durch funktionierenden Code ersetzt. Ich habe das Problem behoben, indem ich neue Threads speziell zum Speichern der aktualisierten Daten in der Datenbank erstellt habe. Aber ich frage mich immer noch: Warum ist das notwendig?

Code: Select all

@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() # db_record.save()

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() # db_record.save()

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post