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

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

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

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


当前回答

我相信@AnujGupta的答案是正确的。然而,回滚本身会引发一个异常,你应该捕获和处理:

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

如果你发现你在不同的save()位置重写这段代码,你可以extract-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()作为提取的方法仍然很方便,以便在需要特定处理的情况下手动使用它,而通用的装饰器处理还不够。

其他回答

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

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

我在postgres终端上运行故障事务时遇到了类似的行为。在此之后什么都没有通过,因为数据库处于错误状态。但是,作为一个快速解决方案,如果可以避免回滚事务。以下是我的诀窍:

提交;

这是一个糟糕的sql执行问题,它不允许其他查询执行,直到前一个查询被挂起/回滚。

在PgAdmin4-4.24中有一个回滚选项,可以尝试一下。

只需使用回滚

示例代码

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

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

要同步你的django db,在你的app目录中,在终端中,输入:

$ python manage.py syncdb

编辑:注意,如果你正在使用django-south,运行'$ python manage.py migrate'命令也可以解决这个问题。

编码快乐!