web-dev-qa-db-ja.com

Django-DB-Migrations:保留中のトリガーイベントがあるため、TABLEを変更できません

TextFieldからnull = Trueを削除したい:

-    footer=models.TextField(null=True, blank=True)
+    footer=models.TextField(blank=True, default='')

スキーマの移行を作成しました:

manage.py schemamigration fooapp --auto

一部のフッター列にはNULLが含まれているため、移行を実行すると、このerrorが取得されます。

Django.db.utils.IntegrityError:列「フッター」にヌル値が含まれています

これをスキーマの移行に追加しました。

    for sender in orm['fooapp.EmailSender'].objects.filter(footer=None):
        sender.footer=''
        sender.save()

今私は得る:

Django.db.utils.DatabaseError: cannot ALTER TABLE "fooapp_emailsender" because it has pending trigger events

なにが問題ですか?

96
guettli

すべての移行はトランザクション内にあります。 PostgreSQLでは、1つのトランザクションでテーブルを更新してからテーブルスキーマを変更しないでください。

データの移行とスキーマの移行を分割する必要があります。最初に、次のコードを使用してデータ移行を作成します。

 for sender in orm['fooapp.EmailSender'].objects.filter(footer=None):
    sender.footer=''
    sender.save()

次に、スキーマ移行を作成します。

manage.py schemamigration fooapp --auto

これで2つのトランザクションができ、2つのステップでの移行が機能するはずです。

110
guettli

これのもう1つの理由は、列をNOT NULL実際に既にNULL値を持っている場合。

111
maazza

この問題が発生しました。スキーマの移行でdb.start_transaction()およびdb.commit_transaction()を使用して、データの変更をスキーマの変更から分離することもできます。おそらく、個別のデータ移行を行うほどクリーンではありませんが、私の場合は、スキーマ、データ、そして別のスキーマ移行が必要になるため、一度にすべてを実行することにしました。

9
clime