![](/img/trans.png)
[英]DatabaseError: current transaction is aborted, commands ignored until end of transaction block - in incognite mode but no error in normal
[英]DatabaseError: current transaction is aborted, commands ignored until end of transaction block?
我收到了很多錯誤消息:
"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 文檔
所以,我遇到了同樣的問題。 我在這里遇到的問題是我的數據庫沒有正確同步。 簡單的問題似乎總是引起最大的焦慮……
要同步您的 django 數據庫,請從您的應用程序目錄中的終端中鍵入:
$ python manage.py syncdb
編輯:請注意,如果您使用的是 django-south,運行“$ python manage.py migrate”命令也可以解決此問題。
快樂編碼!
在 Flask 中你只需要寫:
curs = conn.cursor()
curs.execute("ROLLBACK")
conn.commit()
PS 文檔在這里https://www.postgresql.org/docs/9.4/static/sql-rollback.html
根據我的經驗,這些錯誤是這樣發生的:
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/ 開發/參考/數據庫/#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;
我在這里遇到了類似的錯誤。 我在這個鏈接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 的以下查詢不會返回錯誤。
我有 silimar 問題。 解決方案是遷移數據庫( manage.py syncdb
或manage.py schemamigration --auto <table name>
如果您使用南)。
在 Flask shell 中,我需要做的就是使用session.rollback()
來解決這個問題。
你只需要運行
rollback;
在 PostgreSQL 中,就是這樣!
我遇到了這個問題,由於錯誤事務沒有正確結束而出現錯誤,我在這里找到了事務控制命令的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
來結束錯誤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)”禁用事務
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.