2017-07-21 1 views
0

J'ai un problème avec les objets de stockage Django. Quand j'essaye de faire quelque chose dans un bloc try/except, si tout va bien, mon objet est persistant. Mais si une exception est levée (pas à cause de l'objet .save()), rien n'est stocké.Django ORM ne stocke pas à l'intérieur try/except block

Un exemple:

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

cas OK:

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

KO cas:

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

Seulement dans le cas OK, objet MyModel persistée. Je peux voir, en déboguant, que dans les deux cas l'objet est créé dans la mémoire RAM (MyModel.objects.all() le contient) mais pas dans la base de données. Et si une exception est levée, il semble qu'elle effectue une annulation de transaction (je n'utilise pas de blocs de transaction.)

Je ne sais pas si c'est le comportement souhaité de l'ORM. Si c'est le cas, que puis-je faire pour stocker des objets dans un bloc try, même si une exception est levée après les avoir sauvegardés? (Disons que je ne devrais pas supprimer cette try/sauf emballage)

Répondre

1

Ceci est le comportement par défaut si ATOMIC_REQUESTS sont réglés sur TRUE dans la définition de votre base de données dans votre settings.py

Documentation pour les demandes atomiques déclare:

Avant d'appeler une fonction de vue, Django lance une transaction. Si la réponse est produite sans problème, Django valide la transaction. Si la vue produit une exception, Django annule la transaction] 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 
    } 
} 

set ATOMIC_REQUESTS à False si vous voulez garder vos transactions de base de données lorsque votre code déclenche une exception.

+0

Donc le problème n'est pas le bloc try/except, mais toute la fonction de vue? Alors, @ transaction.non_atomic_requests seulement pour cette vue pourrait résoudre mon problème sans changer les paramètres pour l'ensemble du projet? – JorgeDLuffy

+1

Je pense que les transactions sont seulement annulées si vous avez défini ATOMIC_REQUESTS sur True dans vos paramètres comme je l'ai décrit ci-dessus. Si tel est le cas, marquer votre vue avec @ transaction.non_atomic_requests comme vous l'avez suggéré devrait éviter cette annulation. Voir aussi https://stackoverflow.com/questions/31734306/django-transactions-atomic-requests – matyas