2017-07-21 3 views
0

Ich habe ein Problem mit Django Objekte zu speichern. Wenn ich versuche, etwas in einem try/except-Block zu tun, bleibt mein Objekt bestehen, wenn alles in Ordnung ist. Wenn jedoch eine Ausnahme ausgelöst wird (nicht wegen der .save()), wird nichts gespeichert.Django ORM nicht im Versuch speichern/außer Block

Ein Beispiel:

def my_function(raise_exc): 
    MyModel.objects.create(name='name') 
    if raise_exc: 
    raise Exception() 
    return 

OK Fall:

raise_exc = False 
try: 
    my_function(raise_exc=raise_exc) 
except Exception: 
    pass 

KO Fall:

raise_exc = True 
try: 
    my_function(raise_exc=raise_exc) 
except Exception: 
    pass 

Nur im OK-Fall wird MyModel Objekt beibehalten. Ich kann durch das Debuggen sehen, dass in beiden Fällen das Objekt im RAM-Speicher erstellt wird (MyModel.objects.all() enthält es), aber nicht in der Datenbank. Und wenn eine Ausnahme ausgelöst wird, sieht es so aus, als ob es einen Transaktions-Rollback durchführt (ich verwende keine Transaktionsblöcke. Nur für den Fall).

Ich weiß nicht, ob dies das gewünschte Verhalten des ORM ist. Wenn ja, was kann ich tun, um Objekte in einem try-Block zu speichern, auch wenn nach dem Speichern eine Ausnahme ausgelöst wird? (Sagen wir mal, dass ich nicht entfernen, dass try/except-Wrapper)

Antwort

1

Dies ist das Standardverhalten, wenn ATOMIC_REQUESTS auf TRUE in Ihrer Datenbankdefinition in Ihrer settings.py

Dokumentation für die Atomanforderungen festgelegt sind heißt es:

Bevor eine View-Funktion aufgerufen wird, startet Django eine Transaktion. Wenn die Antwort ohne Probleme erstellt wird, wird die Transaktion von Django bestätigt. Wenn die Ansicht eine Ausnahme erzeugt, rollt Django die Transaktion zurück] 1

DATABASES = { 
    'default': { 
     'ENGINE': '', 
     'NAME': '', 
     'USER': '', 
     'PASSWORD': '!', 
     'HOST': '127.0.0.1', # Or an IP Address that your DB is hosted on 
     'PORT': '', 
     'ATOMIC_REQUESTS': True 
    } 
} 

Satz ATOMIC_REQUESTS auf False, wenn Sie Ihre Datenbank Transaktionen behalten möchten, wenn Ihr Code eine Ausnahme auslöst.

+0

Also ist das Problem nicht der Versuch/außer Block, aber die ganze Ansicht Funktion? Dann @ transaction.non_atomic_requests nur für diese Ansicht könnte mein Problem lösen, ohne die Einstellungen für das gesamte Projekt zu ändern? – JorgeDLuffy

+1

Ich denke, die Transaktionen werden nur zurückgesetzt, wenn Sie ATOMIC_REQUESTS in Ihren Einstellungen auf True gesetzt haben, wie ich oben beschrieben habe. Wenn dies der Fall ist, sollten Sie dieses Rollback vermeiden, indem Sie Ihre Ansicht mit @ transaction.non_atomic_requests markieren, wie Sie es vorgeschlagen haben. Siehe auch https://stackoverflow.com/questions/31734306/django-transactions-atomic-requests – matyas

Verwandte Themen