メッセージで多くのエラーが発生しました:
"DatabaseError: current transaction is aborted, commands ignored until end of transaction block"
Django プロジェクトのデータベース エンジンとして python-psycopg から python-psycopg2 に変更された後。
コードは同じままですが、これらのエラーの原因がわかりません。
メッセージで多くのエラーが発生しました:
"DatabaseError: current transaction is aborted, commands ignored until end of transaction block"
Django プロジェクトのデータベース エンジンとして python-psycopg から python-psycopg2 に変更された後。
コードは同じままですが、これらのエラーの原因がわかりません。
これは、クエリがエラーを生成し、最初にトランザクションをロールバックせずに別のクエリを実行しようとしたときに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 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
2番目のクエリには何も問題はありませんが、実際のエラーが検出されたため、2番目のクエリは(情報量がはるかに少ない)エラーを発生させるクエリです。
編集:これは、except
句がキャッチした場合IntegrityError
(または他の低レベルのデータベース例外)にのみ発生します。このようなDoesNotExist
エラーがキャッチされた場合DoesNotExist
、トランザクションが破損しないため、エラーは発生しません。
ここでのレッスンは、try /except/passを実行しないことです。
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 モード
DATABASES['default'] = {
#.. you usual options...
'OPTIONS': {
'autocommit': True,
}
}
パフォーマンスに関する重要な考慮事項 (またはその他のタイプ) があるかどうかはわかりません。
対話型シェルでこれを取得し、迅速な修正が必要な場合は、次のようにします。
from django.db import connection
connection._rollback()
この回答で最初に見られた
端末で誤動作したトランザクションを実行しているときに、同様の動作に遭遇しましたpostgres
。database
は の状態であるため、この後は何も実行されませんでしerror
た。ただし、回避する余裕がある場合は、簡単な修正としてrollback transaction
. 以下は私のためにトリックをしました:
COMMIT;
シリマーの問題があります。解決策は、dbを移行することでした(manage.py syncdb
またはmanage.py schemamigration --auto <table name>
南を使用する場合)。
@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()
も、特定の処理が必要な場合に手動で使用する必要があり、一般的なデコレーターの処理では不十分な場合に備えて、抽出されたメソッドとして保持しておくと便利です。
私もこのエラーが発生しましたが、コードが125文字の文字列を100文字の列に格納しようとしていた別のより関連性の高いエラーメッセージを隠していました:
DatabaseError: value too long for type character varying(100)
上記のメッセージが表示されるようにするには、コードをデバッグする必要がありました。
DatabaseError: current transaction is aborted
「set_isolation_level(0)」を介してトランザクションを無効にすることができます