我收到了很多错误消息:
"DatabaseError: current transaction is aborted, commands ignored until end of transaction block"
在从 python-psycopg 更改为 python-psycopg2 作为 Django 项目的数据库引擎之后。
代码保持不变,只是不知道这些错误来自哪里。
我收到了很多错误消息:
"DatabaseError: current transaction is aborted, commands ignored until end of transaction block"
在从 python-psycopg 更改为 python-psycopg2 作为 Django 项目的数据库引擎之后。
代码保持不变,只是不知道这些错误来自哪里。
当查询产生错误并且您尝试运行另一个查询而不首先回滚事务时,这就是 postgres 所做的。(您可能会将其视为一项安全功能,以防止您损坏数据。)
要解决此问题,您需要找出代码中执行错误查询的位置。在您的 postgresql 服务器中使用log_statement和log_min_error_statement选项可能会有所帮助。
要消除错误,请在修复代码后回滚最后一个(错误的)事务:
from django.db import transaction
transaction.rollback()
您可以使用 try-except 来防止错误发生:
from django.db import transaction, DatabaseError
try:
a.save()
except DatabaseError:
transaction.rollback()
参考:Django 文档
在 Flask 中,您只需要编写:
curs = conn.cursor()
curs.execute("ROLLBACK")
conn.commit()
PS 文档在这里https://www.postgresql.org/docs/9.4/static/sql-rollback.html
所以,我遇到了同样的问题。我在这里遇到的问题是我的数据库没有正确同步。简单的问题似乎总是引起最焦虑...
要同步您的 django db,请从您的应用程序目录中的终端中输入:
$ python manage.py syncdb
编辑:请注意,如果您使用的是 django-south,则运行“$ python manage.py migrate”命令也可以解决此问题。
快乐编码!
根据我的经验,这些错误是这样发生的:
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
不会破坏事务。
这里的教训是不要尝试/除了/通过。
我认为在使用 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,
}
}
我不确定是否有重要的性能考虑(或任何其他类型)。
只使用回滚
示例代码
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);")
如果您在交互式 shell 中遇到此问题并需要快速修复,请执行以下操作:
from django.db import connection
connection._rollback()
最初在这个答案中看到
postgres
在终端上运行故障事务时,我遇到了类似的行为。在此之后没有发生任何事情,因为database
处于error
. 但是,作为一种快速解决方法,如果您有能力避免rollback transaction
. 以下为我做了诀窍:
COMMIT;
我有类似的问题。解决方案是迁移数据库(manage.py syncdb
或者manage.py schemamigration --auto <table name>
如果您使用南)。
你只需要运行
rollback;
在 PostgreSQL 中,就是这样!
我在这里遇到了类似的错误。我在此链接https://www.postgresqltutorial.com/postgresql-python/transaction/中找到了答案
client = PsqlConnection(config)
connection = client.connection
cursor = client.cursor
try:
for query in list_of_querys:
#query format => "INSERT INTO <database.table> VALUES (<values>)"
cursor.execute(query)
connection.commit()
except BaseException as e:
connection.rollback()
执行此操作,您发送到 postgresql 的以下查询将不会返回错误。
在 Flask shell 中,我需要做的就是session.rollback()
解决这个问题。
我遇到了这个问题,由于错误事务没有正确结束而出现错误,我在这里postgresql_transactions
找到了事务控制命令
事务控制
以下命令用于控制事务
BEGIN TRANSACTION − To start a transaction.
COMMIT − To save the changes, alternatively you can use END TRANSACTION command.
ROLLBACK − To rollback the changes.
所以我使用END TRANSACTION
来结束错误事务,代码如下:
for key_of_attribute, command in sql_command.items():
cursor = connection.cursor()
g_logger.info("execute command :%s" % (command))
try:
cursor.execute(command)
rows = cursor.fetchall()
g_logger.info("the command:%s result is :%s" % (command, rows))
result_list[key_of_attribute] = rows
g_logger.info("result_list is :%s" % (result_list))
except Exception as e:
cursor.execute('END TRANSACTION;')
g_logger.info("error command :%s and error is :%s" % (command, e))
return result_list
我也遇到了这个错误,但它掩盖了另一个更相关的错误消息,其中代码试图在 100 个字符的列中存储一个 125 个字符的字符串:
DatabaseError: value too long for type character varying(100)
我必须通过代码进行调试才能显示上述消息,否则会显示
DatabaseError: current transaction is aborted
作为对@priestc 和@Sebastian 的回应,如果你做这样的事情怎么办?
try:
conn.commit()
except:
pass
cursor.execute( sql )
try:
return cursor.fetchall()
except:
conn.commit()
return None
我刚刚尝试了这段代码,它似乎可以工作,默默地失败而不必关心任何可能的错误,并且在查询良好时工作。
我相信@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
我正在使用 python 包 psycopg2 并在查询时收到此错误。我一直只运行查询,然后运行执行功能,但是当我重新运行连接时(如下所示),它解决了问题。所以重新运行脚本上方的内容,即连接,因为正如上面有人所说,我认为它失去了连接或不同步或其他什么。
connection = psycopg2.connect(user = "##",
password = "##",
host = "##",
port = "##",
database = "##")
cursor = connection.cursor()
您可以通过“set_isolation_level(0)”禁用事务