DatabaseError:当前事务中止,忽略命令,直到事务块结束

我收到很多错误消息:

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

之后从python-psycopg更改为python-psycopg2作为Django项目的数据库引擎。

代码保持不变,只是不知道这些错误来自哪里。

这是postgres在查询产生错误时所做的事情,并且您在不首先回滚事务的情况下尝试运行另一个查询。 为了解决这个问题,你需要弄清楚代码中的错误查询是在哪里执行的。 在postgresql服务器中使用log_statement和log_min_error_statement选项可能会有帮助。

为了摆脱错误,在修复代码之后回滚最后一个(错误的)事务

 from django.db import transaction transaction.rollback() 

您可以使用try-except来防止发生错误:

 from django.db import transaction, DatabaseError try: a.save() except DatabaseError: transaction.rollback() 

请参阅: Django文档

所以,我遇到了同样的问题。 我在这里遇到的问题是我的数据库没有正确同步。 简单的问题似乎总是引起最大的焦虑。

要在您的应用程序目录中,在terminal中同步您的django数据库,请键入:

 $ python manage.py syncdb 

编辑:请注意,如果您使用的是django-south,则运行“$ python manage.py migrate”命令也可能会解决此问题。

快乐的编码!

根据我的经验,这些错误就是这样发生的:

 try: code_that_executes_bad_query() # transaction on DB is now bad except: pass # transaction on db is still bad code_that_executes_working_query() # raises transaction error 

第二个查询没有任何问题,但是由于真正的错误被捕获,第二个查询是引发(信息量更less)错误的查询。

编辑:只有当except子句捕获IntegrityError (或任何其他低级别的数据库exception)时,才会发生这种情况。如果您捕获了像DoesNotExist这样的错误,则不会出现此错误,因为DoesNotExist不会破坏事务。

这里的教训是不要尝试/除了/通过。

我认为在使用PostgreSQL时,priestc提到的模式更可能是这个问题的常见原因。

不过,我觉得这种模式是有效的,我不认为这个问题应该是总是避免的原因。 例如:

 try: profile = user.get_profile() except ObjectDoesNotExist: profile = make_default_profile_for_user(user) do_something_with_profile(profile) 

如果你对这种模式感觉不错,但是想要避免显式的事务处理代码,那么你可能需要考虑打开自动提交模式(PostgreSQL 8.2+): https ://docs.djangoproject.com/en/ 开发/ REF /数据库/#自动提交模式

 DATABASES['default'] = { #.. you usual options... 'OPTIONS': { 'autocommit': True, } } 

我不确定是否有重要的性能考虑(或任何其他types)。

如果你在交互式shell中得到这个,并且需要快速修复,那么执行下面的操作:

 from django.db import connection connection._rollback() 

最初看到这个答案

我有silimar问题。 解决scheme是迁移数据库( manage.py syncdbmanage.py schemamigration --auto <table name>如果您使用南)。

我在postgresterminal上运行有故障的事务时遇到类似的行为。 之后没有任何事情发生,因为database处于error状态。 但是,如果能够避免rollback transaction ,则可以快速修复。 以下为我做的伎俩:

COMMIT;

我只是有这个错误,但它掩盖了另一个更相关的错误消息代码试图存储在一个100个字符列中的125个字符的string:

 DatabaseError: value too long for type character varying(100) 

我不得不通过代码debugging以显示上述消息,否则显示

 DatabaseError: current transaction is aborted 

回应@priestc和@Sebastian,如果你做这样的事情呢?

 try: conn.commit() except: pass cursor.execute( sql ) try: return cursor.fetchall() except: conn.commit() return None 

我只是试了这个代码,它似乎工作,失败的沉默,而不必关心任何可能的错误,并在查询是好的时候工作。

我相信@ AnujGupta的答案是正确的。 然而,回滚本身可能引发一个你应该捕捉和处理的exception:

 from django.db import transaction, DatabaseError try: a.save() except DatabaseError: try: transaction.rollback() except transaction.TransactionManagementError: # Log or handle otherwise 

如果您发现您在各种save()位置重写了此代码,则可以提取-method方法:

 import traceback def try_rolling_back(): try: transaction.rollback() log.warning('rolled back') # example handling except transaction.TransactionManagementError: log.exception(traceback.format_exc()) # example handling 

最后,你可以使用装饰器来保护使用save()方法来保护它:

 from functools import wraps def try_rolling_back_on_exception(fn): @wraps(fn) def wrapped(*args, **kwargs): try: return fn(*args, **kwargs) except: traceback.print_exc() try_rolling_back() return wrapped @try_rolling_back_on_exception def some_saving_method(): # ... model.save() # ... 

即使你实现了上面的装饰器,仍然可以方便的把try_rolling_back()作为一个提取的方法,以防需要特定处理的情况下手工使用它,而通用的装饰器处理是不够的。

这对我来说是非常奇怪的行为。 我很惊讶,没有人想到保存点。 在我的代码失败的查询是预期的行为:

 from django.db import transaction @transaction.commit_on_success def update(): skipped = 0 for old_model in OldModel.objects.all(): try: Model.objects.create( group_id=old_model.group_uuid, file_id=old_model.file_uuid, ) except IntegrityError: skipped += 1 return skipped 

我已经改变了代码这种方式来使用保存点:

 from django.db import transaction @transaction.commit_on_success def update(): skipped = 0 sid = transaction.savepoint() for old_model in OldModel.objects.all(): try: Model.objects.create( group_id=old_model.group_uuid, file_id=old_model.file_uuid, ) except IntegrityError: skipped += 1 transaction.savepoint_rollback(sid) else: transaction.savepoint_commit(sid) return skipped 

你可以通过“set_isolation_level(0)”来禁用事务