結束命令我得到了很多與消息的錯誤: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