【发布时间】:2019-10-21 10:13:34
【问题描述】:
我有一个导入 Excel 文件的 Django 视图,如果发生异常,我想捕获它们并全部报告,并回滚所有保存。即使我使用了 non_atomic_requests 装饰器,我也会收到 TransactionManagementError。
由于我也在使用 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})
我在 set_autocommit 上收到一个 TransactionManagementError 指示原子块处于活动状态,即使我知道装饰器会禁用它。几年前,我使用了旧的 commit_manually 装饰器,效果很好。
文件“C:\Users\csullivan\responsive\finance\views.py”,第 25 行,在 gl_upload 中 transaction.set_autocommit(False) 文件“C:\Users\csullivan\responsive\env\lib\site-packages\django\db\transaction.py”,第 30 行,在 set_autocommit 返回 get_connection(using).set_autocommit(autocommit) 文件“C:\Users\csullivan\responsive\env\lib\site-packages\django\db\backends\base\base.py”,第 394 行,在 set_autocommit self.validate_no_atomic_block() 文件“C:\Users\csullivan\responsive\env\lib\site-packages\django\db\backends\base\base.py”,第 433 行,在 validate_no_atomic_block “当‘原子’块处于活动状态时,这是禁止的。”) django.db.transaction.TransactionManagementError:当“原子”块处于活动状态时,这是禁止的。
【问题讨论】:
标签: python django django-views