我收到了很多错误的信息:

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

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

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


当前回答

我认为在使用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/dev/ref/databases/#autocommit-mode

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

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

其他回答

我认为在使用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/dev/ref/databases/#autocommit-mode

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

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

当查询产生错误,而您试图在不先回滚事务的情况下运行另一个查询时,postgres就会这样做。(你可能会认为这是一个安全功能,防止你破坏你的数据。)

要解决这个问题,您需要找出在代码中执行错误查询的位置。在postgresql服务器中使用log_statement和log_min_error_statement选项可能会有所帮助。

我也遇到了类似的问题。解决方案是迁移db (manage.py syncdb或manage.py schemmigration——auto <表名>如果您使用south)。

只需使用回滚

示例代码

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);")

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

from django.db import transaction
transaction.rollback()

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

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

参考:Django文档