Django + Postgres:“当前事务被中止,命令被忽略,直到事务块结束”
我已经开始在Django / Postgres站点上工作了。 有时我在manage.py shell
工作,并且不小心做了一些导致错误的数据库操作。 然后,我根本无法执行任何数据库操作,因为对于我尝试执行的任何数据库操作,我收到错误消息:
current transaction is aborted, commands ignored until end of transaction block
我目前的解决方法是重新启动shell,但我应该find一种方法来解决这个问题,而不会放弃我的shell会话。
(我读过这个和这个 ,但是他们没有给出可执行的指令来说明如何从shell执行操作。)
你可以试试这个:
from django.db import connection connection._rollback()
这个问题的更详细的讨论可以在这里find
这有时发生在我身上,往往是失踪
manage.py migrate
要么
manage.py syncdb
这里也提到了
如果你的models.py有一个模式迁移挂起的话,它也可能发生。 与南方,你需要更新架构。
manage.py schemamigration mymodel --auto
检查这个
快速的答案通常是打开数据库级自动提交,通过添加:
'OPTIONS': {'autocommit': True,}
到数据库设置。
将备份还原到完全空的数据库后出现此错误。 跑完后就消失了:
./manage syncdb
也许有一些内部模型从转储丢失…
警告:下面的补丁可能会导致事务在db上保持打开状态(至less在postgres中)。 不是100%确定(以及如何解决),但我强烈build议不要在生产数据库上进行下面的修补程序。
由于接受的答案不能解决我的问题 – 一旦我得到任何数据库错误,我不能做任何新的数据库操作,即使手动回滚 – 我想出了我自己的解决scheme。
当我运行Django-shell时,我修补了Django以在出现任何错误时立即closures数据库连接。 这样,我永远不必考虑回滚事务或处理连接。
这是我在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
如果在运行migrate
(South)时碰巧遇到这样的错误,那么您可能会在数据库模式中进行很多更改,并希望一次处理它们。 Postgres对此有点讨厌。 什么总是有效的,就是把一个大的迁移分成更小的步骤。 最有可能的是,您正在使用版本控制系统。
- 您当前的版本
- 提交n1
- 提交n2
- 提交n3
- 提交n4#db更改
- 提交n5
- 提交n6
- 提交n7#db changse
- 提交n8
- 提交n9#db更改
- 提交n10
所以,有上述情况,做如下:
- 结帐库“n4”,然后syncdb和迁移。
- 结帐库“n7”,然后syncdb和迁移。
- 结帐库到“n10”,然后syncdb和迁移。
你完成了。 🙂
它应该完美运行。
如果您在1.6之前使用django版本,那么您应该使用Christophe的优秀的xact模块。
xact是在PostgreSQL的Django应用程序中合理处理事务的一个配方。
注意:从Django 1.6开始,xact的function将作为primefaces装饰器合并到Django核心中。 使用xact的代码应该能够通过search和replace来迁移到primefaces级。 primefaces在PostgreSQL以外的数据库上工作,是线程安全的,并有其他好的function; 切换到它,当你可以!
我将以下内容添加到我的设置文件中,因为当我“玩”时,我喜欢自动提交function,但是当我的网站正在运行时,不希望它处于活动状态。
所以要在shell中自动提交,我做这个小黑客:
import sys if 'shell' in sys.argv or sys.argv[0].endswith('pydevconsole.py'): DATABASES['default']['OPTIONS']['autocommit'] = True
注意:第二部分是因为我在PyCharm工作,它不直接运行manage.py
我在Django 1.7中遇到了这个错误。 当我在文档中读到的时候
在Django的默认模式下,这个问题不会发生,atomic()会自动处理它。
我有点怀疑。 发生错误,当我尝试运行迁移。 原来,我的一些模型有my_field = MyField(default=some_function)
。 这个函数作为一个字段的默认工作正常与sqlite和mysql(我有一些导入错误,但我设法使它的工作),虽然它似乎不适用于postgresql,它打破了迁移到点我没有事件得到一个有用的错误消息,而是来自问题标题。