结束命令我得到了很多与消息的错误:DatabaseError:当前事务被中止,忽略,直到事务块
"DatabaseError: current transaction is aborted, commands ignored until end of transaction block"
蟒蛇,psycopg改变到Python-psycopg2后的Django项目的数据库引擎。
代码保持不变,只是不知道这些错误来自哪里。
结束命令我得到了很多与消息的错误:DatabaseError:当前事务被中止,忽略,直到事务块
"DatabaseError: current transaction is aborted, commands ignored until end of transaction block"
蟒蛇,psycopg改变到Python-psycopg2后的Django项目的数据库引擎。
代码保持不变,只是不知道这些错误来自哪里。
这是postgres在查询产生错误时所做的事情,并且您尝试在不首先回滚事务的情况下运行其他查询。为了解决这个问题,你需要弄清楚代码中哪个地方正在执行错误的查询。在你的postgresql服务器中使用log_statement和log_min_error_statement选项可能会有帮助。
问题是当我使用python-psycopg时,没有提出这样的错误。 psycopg2是否实现了与postgres对话的不同机制? – jack 2010-06-05 06:28:36
与服务器交谈的方法可能并不重要,但可能以前使用的版本默认为自动提交模式,而新版本则不行。错误可能仍然发生,但您可能更容易错过它。自旧版本以来,数据类型转换或其他内容也可能发生更改。无论如何,最好的解决办法是跟踪错误的查询,以便查看错误。 – 2010-06-05 07:25:22
所以,我遇到了同样的问题。我在这里遇到的问题是我的数据库没有正确同步。简单的问题似乎总是造成最大的焦虑...
要同步Django的数据库,从您的应用程序目录中,终端类型中:
$ python manage.py syncdb
编辑:请注意,如果您正在使用django-南,运行'$ python manage.py migrate'命令也可以解决这个问题。
编码愉快!
Upvoted表明明显。我不会放弃这一点,因为它可能不是所寻求的答案。 – 2011-10-28 11:17:15
我修正了'python manage.py migrate
@Clayton - 你没有说,但我假设你使用'django-south' - 'migrate'命令没有被构建到django中。 – 2012-04-18 03:36:53
你可以通过禁用事务“set_isolation_level(0)”
根据我的经验,这些错误的发生是这样的:
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
这没有什么错第二次查询,但由于真正的错误是第二个查询是引发(更少信息量)错误的查询。
编辑:如果except
子句捕获IntegrityError
(或任何其他低级别的数据库除外),这只是发生,如果赶上像DoesNotExist
这个错误不会来了,因为DoesNotExist
不会破坏交易。
这里的教训是不要尝试/除了/通过。
我认为priestc提到的模式更可能是使用PostgreSQL时这个问题的通常原因。
但是我觉得这种模式是有效的用法,我不认为这个问题应该是一个总是避免它的理由。例如:
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/dev/ref/databases/#autocommit-mode
DATABASES['default'] = {
#.. you usual options...
'OPTIONS': {
'autocommit': True,
}
}
我不确定是否有重要的性能考虑因素(或任何其他类型)。
我有silimar问题。解决方案是迁移db(如果使用南方,则为manage.py syncdb
或manage.py schemamigration --auto <table name>
)。
为了摆脱错误的,回滚最后的(错误)交易你已经固定后您的代码:
from django.db import transaction
transaction.rollback()
您可以使用尝试 - 除了防止错误的发生:
from django.db import transaction, DatabaseError
try:
a.save()
except DatabaseError:
transaction.rollback()
我只是有这个错误太多,但它的掩蔽另一个更相关的错误消息,其中该代码试图一个125个字符的字符串存储在100个字符柱:
DatabaseError: value too long for type character varying(100)
我不得不通过对上述消息的代码调试展现出来,否则它会显示
DatabaseError: current transaction is aborted
*您如何做到这一点可能有用... – 2013-03-15 15:57:12
作为对@priestc和@Sebastian的回应,如果你做这样的事情呢?
try:
conn.commit()
except:
pass
cursor.execute(sql)
try:
return cursor.fetchall()
except:
conn.commit()
return None
我只是尝试这个代码,它似乎工作,默默失败而不必在意任何可能的错误,当查询是很好的工作。
如果你得到这个,而在交互shell,需要速战速决,这样做:
from django.db import connection
connection._rollback()
原本出现在this answer
我相信@ AnujGupta的答案是正确的。然而回滚本身可以抛出一个异常,你应该能够捕获并处理:
from django.db import transaction, DatabaseError
try:
a.save()
except DatabaseError:
try:
transaction.rollback()
except transaction.TransactionManagementError:
# Log or handle otherwise
如果你发现你改写各种save()
位置的代码,你可以提取法:
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
我遇到过类似的行为,而postgres
终端上运行中的故障交易。此后没有任何事情发生,因为database
处于error
的状态。但是,如果您能承受,则可以快速修复,以避免rollback transaction
。下面的伎俩对我来说:
COMMIT;
只使用回滚
示例代码
try:
cur.execute("CREATE TABLE IF NOT EXISTS test2 (id serial, qa text);")
except:
cur.execute("rollback")
cur.execute("CREATE TABLE IF NOT EXISTS test2 (id serial, qa text);")
在瓶,你只需要写:
curs = conn.cursor()
curs.execute("ROLLBACK")
conn.commit()
附:文档在这里https://www.postgresql.org/docs/9.4/static/sql-rollback.html
我很好奇你对这个问题的最终解决方案是什么?我有这个相同的问题,但由于我的托管服务提供商不记录查询错误,迄今为止不可能找出问题所在。 – user27478 2011-10-20 07:39:43
当我使用数据库表作为缓存后端时,我最终跟踪到了我的问题。 Django的bug:https://code.djangoproject.com/ticket/11569 StackOverflow讨论:http://stackoverflow.com/questions/1189541/django-cache-set-causing-duplicate-key-error – user27478 2011-10-21 19:30:19
仅供参考如果你是只用psycopg2而不用django,'conn.rollback()'(其中conn是你的连接对象)将清除错误,所以你可以运行其他查询 – User 2013-12-08 11:56:56