Django: The correct way to recover from IntegrityError

What is the correct way to recover from IntegrityErroror any other errors that could lead to the loss of my transactions without using manual transaction management?

In my application, I ran into problems with IntegrityErrorwhich I want to recover, which will bring later database activity, leaving me with:

DatabaseError: current transaction is aborted, commands ignored until end of transaction block` 

for all database operations after ignoring IntegrityErrors.

This code block should reproduce the error that I see

from django.db import transaction

try:
    MyModel.save() # Do a bad save that will raise IntegrityError
except IntegrityError:
    pass

MyModel.objects.all() # raises DatabaseError: current transaction is aborted, commands ignored until end of transaction block

According to the docs , the solution to recover after IntegrityErroris to roll back the transaction. But the following code leads to TransactionManagementError.

from django.db import transaction

try:
    MyModel.save()
except IntegrityError:
    transaction.rollback() # raises TransactionManagementError: This code isn't under transaction management

MyModel.objects.all() # Should work

EDIT: TransactionManagementError, except a:

connection._cursor().connection.rollback()

django transaction.rollback(), MyModel.objects.all() , , " ". , , (, , , autocommit), , .

№ 2: , , ? , autocommit, , .

EDIT # 3:. , django 1.4 ( ) , Model.objects.bulk_create() autocommit.

:

  • Django: 1.4 (TransactionMiddleWare )
  • Python: 2.7
  • Postgres: 9.1
+4
1

Django - AutoCommit. , , . [docs]

with transaction.commit_on_success():
    # Your code here. Errors will auto-rollback.

, DATABASES.

'OPTIONS': {'autocommit': True,}

. [docs]

@transaction.commit_manually
def viewfunc(request):

  a.save()
  # open transaction now contains a.save()
  sid = transaction.savepoint()

  b.save()
  # open transaction now contains a.save() and b.save()

  if want_to_keep_b:
      transaction.savepoint_commit(sid)
      # open transaction still contains a.save() and b.save()
  else:
      transaction.savepoint_rollback(sid)
      # open transaction now contains only a.save()

  transaction.commit()
+3

Source: https://habr.com/ru/post/1546449/


All Articles