2012-10-11 9 views
63

トリガイベントを保留しているため、表を変更することはできません。いくつかのフッターの列が含まれているため南:それは私は、TextFieldから真= nullを削除したい

manage.py schemamigration fooapp --auto 

:私はスキーマの移行を作成し

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

NULL私は、マイグレーションを実行する場合、私はこのエラーを取得する:

django.db.utils.IntegrityError: column "footer" contains null values 

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

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 

何が悪いのでしょうか?

+0

この質問は似ています:http://stackoverflow.com/questions/28429933/django-migrations-using-runpython-to-commit-changesそして私にとってより有用な答えがありました。 – SpoonMeiser

答えて

73

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

データの移行とスキーマの移行を分割する必要があります。まず、このコードとデータの移行を作成します。

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

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

manage.py schemamigration fooapp --auto 

今、あなたは二つのトランザクションを持っているし、2つの段階で移行が動作するはずです。

+5

PostgreSQLはおそらく、サーバ(PostgreSQL 9.1)上で失敗したときに私のdevマシン(PostgreSQL 9.4)でデータとスキーマの変更の両方を使って移行を実行したので、そのようなトランザクションに関する動作が変更されました。 –

11

ちょうどこの問題が発生しました。また、スキーマの移行でdb.start_transaction()およびdb.commit_transaction()を使用して、スキーマの変更とデータの変更を区別することもできます。おそらく、別々のデータ移行を持つほどきれいではないかもしれませんが、私の場合はスキーマ、データ、別のスキーマ移行が必要なので、すべてを一度に行うことにしました。

+5

このソリューションの問題は次のとおりです。db.commit_transaction()の後に移行が失敗した場合はどうなりますか?私は3つの移行を使用することをお勧めします。必要な場合は、schema-mig、data-mig、schema-migです。 – guettli

+0

参照:http://django.readthedocs.io/en/latest/ref/migration-operations.html DDLトランザクション(SQLiteおよびPostgreSQL)をサポートするデータベースでは、RunPython操作では、移行ごとに作成されたトランザクション。たとえば、PostgreSQLでは、スキーマ変更とRunPython操作を同じ移行で組み合わせないでください。そうしないと、OperationalErrorのようなエラーが発生する可能性があります。ALTER TABLEには、トリガーイベントが保留中のため、ALTER TABLE "mytable"はできません。 –

75

実際にすでにNULLの値がある場合は、列をNOT NULLに設定しようとしている可能性があります。

+1

これは巨大です!これありがとう。 –

+2

これに対処するには、データ移行を使用するか、手動で(manage.pyシェルを使用して)非準拠の値を入力して更新することができます – mgojohn

+0

@mgojohnどうしますか? – pyramidface

関連する問題