Django + Postgres:“当前事务中止,命令被忽略,直到事务块结束”


75

我已经开始在Django / Postgres网站上工作。有时,我在中工作manage.py shell,而无意中执行了一些导致错误的数据库操作。然后我根本无法执行任何数据库操作,因为对于我尝试执行的任何数据库操作,都会收到错误消息:

current transaction is aborted, commands ignored until end of transaction block

我当前的解决方法是重新启动外壳程序,但是我应该找到一种无需放弃外壳程序会话即可解决此问题的方法。

(我已经读过这个这个,但是他们没有给出有关如何从shell进行操作的可行说明。)


2
我以前遇到过这个问题,找不到解决方法...
Hoff

1
潜在的重复这个,这让几乎相同接受的解决方案...
Cerin

Answers:


117

您可以尝试以下方法:

from django.db import connection
connection._rollback()

有关此问题的更详细讨论,请参见此处


5
此解决方案不适用于我。即使回滚事务,我也无法与数据库进行任何交互。我找到了另一个解决方法,请参见我的答案。
Wolkenarchitekt

1
还有connection.close(),如果_rollback不适合你(@ifischer)做到这一点
灶台

27

有时候这会发生在我身上,通常是失踪了

manage.py migrate 

要么

manage.py syncdb

正如这里也提到的

如果您有来自model.py的schemamigration挂起,它也可能以其他方式发生。对于south,您需要使用来更新架构。

manage.py schemamigration mymodel --auto


3

将备份还原到完全空的数据库后,出现此错误。运行后它消失了:

./manage syncdb 

也许转储中缺少一些内部模型...


2

警告:以下补丁可能会导致事务在数据库上处于打开状态(至少在使用postgres的情况下)。不能100%地确定这一点(以及如何解决),但是我强烈建议不要在生产数据库上进行以下修补程序。

由于可接受的答案不能解决我的问题-出现任何数据库错误后,即使进行了手动回滚,我也无法执行任何新的数据库操作-我想出了自己的解决方案。

当我运行Django-shell时,我会修补Django以在发生任何错误时立即关闭数据库连接。这样,我就不必考虑回滚事务或处理连接。

这是我在Django-shell会话开始时加载的代码:

from django import db
from django.db.backends.util import CursorDebugWrapper
old_execute = CursorDebugWrapper.execute
old_execute_many = CursorDebugWrapper.executemany

def execute_wrapper(*args, **kwargs):
    try:
        old_execute(*args, **kwargs)
    except Exception, ex:
        logger.error("Database error:\n%s" % ex)
        db.close_connection

def execute_many_wrapper(*args, **kwargs):
    try:
        old_execute_many(*args, **kwargs)
    except Exception, ex:
        logger.error("Database error:\n%s" % ex)
        db.close_connection

CursorDebugWrapper.execute = execute_wrapper
CursorDebugWrapper.executemany = execute_many_wrapper

1
如果有人感兴趣:我扩展了django-extensions shell-plus命令,使其能够在启动时加载文件,除了其他东西(包括此补丁),我还可以在其中加载文件。github.com/ifischer/django-extensions
Wolkenarchitekt

1
这肯定会使连接保持打开状态,因为它django.db.close_connection是一个函数,()如果您想让它执行任何操作,都需要调用它;)我也经常这样做django.db.connection.close(),而别名可能是close_connection,不知道。
滚刀

0

如果在运行migrate(南方)时碰巧遇到这样的错误,则可能是您在数据库架构中进行了很多更改,并希望立即处理所有这些更改。Postgres对此有点讨厌。始终有效的是将一个大型迁移分解为较小的步骤。您很可能正在使用版本控制系统。

  • 您当前的版本
  • 提交n1
  • 提交n2
  • 提交n3
  • 提交n4#数据库更改
  • 提交n5
  • 提交n6
  • 提交n7#db changse
  • 提交n8
  • 提交N9#数据库更改
  • 提交n10

因此,鉴于上述情况,请执行以下操作:

  • 检出存储库到“ n4”,然后同步并迁移。
  • 检出存储库到“ n7”,然后同步并迁移。
  • 检出存储库到“ n10”,然后同步并迁移。

这样就完成了。:)

它应该完美运行。


0

如果您在1.6之前使用的是Django版本,则应使用Christophe出色的xact模块。

xact是在PostgreSQL上的Django应用程序中合理处理事务的秘诀。

注意:从Django 1.6开始,xact的功能将作为原子装饰器合并到Django核心中。使用xact的代码应该能够仅通过搜索和替换就可以迁移到原子。atomic在PostgreSQL以外的数据库上工作,是线程安全的,并且具有其他不错的功能;可以的时候切换到它!


0

我将以下内容添加到我的设置文件中,因为我喜欢在“玩耍”时使用自动提交功能,但在我的网站正在运行时不希望它处于活动状态。

因此,要仅在shell中进行自动提交,就要做以下一点技巧:

import sys
if 'shell' in sys.argv or sys.argv[0].endswith('pydevconsole.py'):
    DATABASES['default']['OPTIONS']['autocommit'] = True

注意:第二部分只是因为我在PyCharm工作,而PyCharm不直接运行manage.py


0

我在Django 1.7中遇到此错误。当我在阅读的文档

在Django的默认模式下不会发生此问题,atomic()会自动处理它。

我有点可疑。当我尝试运行迁移时,发生了错误。原来我的一些模特有my_field = MyField(default=some_function)。将此功能作为字段的默认功能可以在sqlite和mysql上正常运行(我有一些导入错误,但我设法使其正常工作),尽管它似乎不适用于postgresql,并且将迁移中断到了我事件没有得到有用的错误消息,而是来自问题标题的消息。


有点死角,但我遇到了这个确切的问题。您设法解决了吗?
奥布里奇斯16-10-11

1
此时无法回忆。我最好的建议是将迁移步骤分为多个迁移文件,看看是否有帮助。模式更改和数据更改不能与postgres
放在

谢谢!事实证明,Django正在吞噬我最终通过pdb看到的错误。基于错误,我通过在依赖项列表中添加了一些其他项来解决此问题。
Aubricus
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.