У меня есть представление Django, которое импортирует файл Excel, и если возникают исключения, я бы хотел отловить их, сообщить обо всех и откатить все сохранения. Я получаю TransactionManagementError, хотя я использовал декоратор non_atomic_requests.
Поскольку я также использую декоратор login_required, я подумал, что они могут мешать друг другу. Сначала я изменил порядок, затем удалил требуемый логин. Без изменений.
Я пытался отключить автоматические транзакции во всем мире. Возможно, я сделал это неправильно, но это не то решение, которое мне нужно.
Я удалил ошибочную строку кода (см. Ниже), но при попытке отката возникла та же ошибка
Он работает на Python 3.7.3 с последней версией Django и использует SQLlite. Я сейчас запускаю его как юнит-тест, хотя, возможно, я злоупотребляю этим термином. Достаточно сказать, что он работает как Django TestCase.
@transaction.non_atomic_requests
@login_required(login_url='/accounts/login/?next=/finance/gl_upload/')
def gl_upload(request):
transaction.set_autocommit(False)
if upriv(request.user, ['admin', 'finance']) == 'admin':
if request.method == 'POST':
... file processing here ...
except Exception as e:
errs.append(format('Exception "{1}" at row {0}\n'.format(p['rownum'], e)))
if errs:
transaction.rollback()
rows_deleted = 0
rows_inserted = 0
print(''.join('Error: {0}\n'.format(e) for e in errs))
else:
transaction.commit()
rows_deleted = Gldata.objects.filter(item='Actual', period_gte=older, period_lte=newest).delete()
rows_inserted = Gldata.objects.filter(item=temp_item).update(item='Actual')
transaction.set_autocommit(True)
print('Deleted: {0}, inserted: {1}'.format(rows_delete, rows_inserted))
return render(request, 'gl_upload.html', {'inserted': rows_inserted, 'removed': rows_deleted, 'errors': errs})
else:
return render(request, 'gl_upload.html', {'form': form})
else:
form = uploadForm()
return render(request, 'gl_upload.html', {'form': form})
Я получаю TransactionManagementError на set_autocommit, указывающий, что атомарный блок активен, даже если я понял, что декоратор отключит его. Несколько лет назад я использовал старый декоратор commit_manually, который работал просто отлично.
Файл "C: \ Users \ csullivan \ responseive \ finance \ views.py", строка 25, в gl_upload
transaction.set_autocommit (False)
Файл "C: \ Users \ csullivan \ responseive \ env \ lib \ site-packages \ django \ db \action.py", строка 30, в set_autocommit
return get_connection (using) .set_autocommit (autocommit)
Файл "C: \ Users \ csullivan \ responseive \ env \ lib \ site-packages \ django \ db \ backends \ base \ base.py", строка 394, в set_autocommit
self.validate_no_atomic_block ()
Файл "C: \ Users \ csullivan \ responseive \ env \ lib \ site-packages \ django \ db \ backends \ base \ base.py", строка 433, в validate_no_atomic_block
«Это запрещено, когда активен« атомарный »блок.»)
django.db.transaction.TransactionManagementError: Это запрещено, когда активен «атомарный» блок.