web-dev-qa-db-ja.com

Django + Postgres:「現在のトランザクションは中止され、コマンドはトランザクションブロックの終わりまで無視されます」

Django/Postgresサイトで作業を開始しました。時々manage.py Shell、およびエラーを引き起こすDBアクションを誤って実行します。その後、私はanyデータベースアクションを行うことができません。

current transaction is aborted, commands ignored until end of transaction block

現在の回避策はシェルを再起動することですが、シェルセッションを中断せずにこれを修正する方法を見つける必要があります。

(私は thisthis を読みましたが、シェルから何をすべきかについての実用的な指示を与えていません。)

71
Ram Rachum

これを試すことができます:

from Django.db import connection
connection._rollback()

この問題はここにあります のより詳細な議論

111

これは時々私に起こります、しばしばそれは行方不明です

manage.py migrate 

または

manage.py syncdb

ここにも述べたように

また、models.pyからスキーマ移行が保留されている場合は、逆のことが起こります。 southでは、スキーマを更新する必要があります。

manage.py schemamigration mymodel --auto
25
yvess

チェックしてください

簡単な答えは通常、次を追加してデータベースレベルの自動コミットを有効にすることです。

'OPTIONS': {'autocommit': True,}

データベース設定へ。

13
Ignacio Pérez

バックアップを完全に空のDBに復元した後にこのエラーが発生しました。実行後に消えました:

./manage syncdb 

たぶんダンプから欠落しているいくつかの内部モデルがあった...

3
Richard

警告:以下のパッチにより、データベースでトランザクションがオープン状態のままになる可能性があります(少なくともpostgresで)。それ(および修正方法)について100%確信はありませんが、パッチを行わないことを強くお勧めします本番データベースでは以下)

受け入れられた答えは私の問題を解決しないので、DBエラーを取得するとすぐに、手動でロールバックしても新しいDBアクションを実行できません-私は自分の解決策を思いつきました。

Django-Shellを実行しているときに、エラーが発生したらすぐにDB接続を閉じるためにDjangoにパッチを適用します。このように、トランザクションのロールバックや処理について考える必要はありません。接続。

これは、Django-Shell-sessionの最初にロードするコードです。

from Django import db
from Django.db.backends.util import CursorDebugWrapper
old_execute = CursorDebugWrapper.execute
old_execute_many = CursorDebugWrapper.executemany

def execute_wrapper(*args, **kwargs):
    try:
        old_execute(*args, **kwargs)
    except Exception, ex:
        logger.error("Database error:\n%s" % ex)
        db.close_connection

def execute_many_wrapper(*args, **kwargs):
    try:
        old_execute_many(*args, **kwargs)
    except Exception, ex:
        logger.error("Database error:\n%s" % ex)
        db.close_connection

CursorDebugWrapper.execute = execute_wrapper
CursorDebugWrapper.executemany = execute_many_wrapper
2
Ingo Fischer

このエラーはDjango 1.7。で読みました。 ドキュメント that

この問題はDjangoのデフォルトモードでは発生せず、atomic()が自動的に処理します。

私は少し疑わしくなりました。移行を実行しようとしたときにエラーが発生しました。一部のモデルにはmy_field = MyField(default=some_function)が含まれていました。この関数をフィールドのデフォルトとして使用すると、sqliteとmysqlでうまく機能しました(いくつかのインポートエラーがありましたが、どうにか機能しました)が、postgresqlでは機能していないようであり、イベントに役立つエラーメッセージは表示されませんでしたが、代わりに質問タイトルのエラーメッセージが表示されました。

0
Eldamir

Django 1.6より前のバージョンを使用している場合は、Christopheの優れた xact モジュールを使用する必要があります。

xactは、Django PostgreSQLのアプリケーションでトランザクションを適切に処理するためのレシピです。

注:Django 1.6以降、xactの機能はDjangoアトミックデコレータとしてのコア。xactを使用するコードは、検索と置換だけでアトミックに移行できる必要があります。できるときはそれに!

0
Jeff Sheffield

migrate(South)の実行中にこのようなエラーが発生した場合、データベーススキーマに多くの変更があり、それらを一度に処理したいことがあります。 Postgresは少し厄介です。常に機能するのは、1つの大きな移行を小さなステップに分割することです。ほとんどの場合、バージョン管理システムを使用しています。

  • 現在のバージョン
  • コミットn1
  • コミットn2
  • コミットn3
  • N4#dbの変更をコミット
  • コミットn5
  • コミットn6
  • N7をコミット#db changse
  • コミットn8
  • N9#dbの変更をコミット
  • コミットn10

したがって、上記の状況になったら、次のようにします。

  • リポジトリを「n4」にチェックアウトしてから、syncdbに移行します。
  • リポジトリを「n7」にチェックアウトしてから、syncdbに移行します。
  • リポジトリを「n10」にチェックアウトしてから、syncdbに移行します。

これで完了です。 :)

完璧に動作するはずです。

0

次のコードを設定ファイルに追加します。「再生中」の自動コミット機能は気に入っていますが、サイトが実行されている場合は自動コミット機能をアクティブにしたくないからです。

シェルで自動コミットを取得するには、この小さなハックを実行します。

import sys
if 'Shell' in sys.argv or sys.argv[0].endswith('pydevconsole.py'):
    DATABASES['default']['OPTIONS']['autocommit'] = True

注:その2番目の部分は、many.pyを直接実行しないPyCharmで働いているからです。

0
blarobot