[python] Django-DB-Migrations : 보류중인 트리거 이벤트가 있으므로 ALTER 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 : “footer”열에 null 값이 있습니다.

나는 이것을 스키마 마이그레이션에 추가했습니다.

    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

뭐가 잘못 되었 니?



답변

이에 대한 또 다른 이유는 열에 NOT NULL실제로 이미 NULL값 이있을 때 열을 설정하려고하기 때문일 수 있습니다.


답변

모든 마이그레이션은 트랜잭션 내부에 있습니다. PostgreSQL에서는 테이블을 업데이트 한 다음 하나의 트랜잭션에서 테이블 스키마를 변경해서는 안됩니다.

데이터 마이그레이션과 스키마 마이그레이션을 분할해야합니다. 먼저 다음 코드를 사용하여 데이터 마이그레이션을 만듭니다.

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

그런 다음 스키마 마이그레이션을 만듭니다.

manage.py schemamigration fooapp --auto

이제 두 개의 트랜잭션이 있으며 두 단계의 마이그레이션이 작동합니다.


답변

이 문제가 발생했습니다. 스키마 마이그레이션에서 db.start_transaction () 및 db.commit_transaction ()을 사용하여 데이터 변경 사항과 스키마 변경 사항을 구분할 수도 있습니다. 아마도 별도의 데이터 마이그레이션이있을만큼 깨끗하지는 않지만 제 경우에는 스키마, 데이터 및 다른 스키마 마이그레이션이 필요하므로 한 번에 모두 수행하기로 결정했습니다.


답변

작업에서 SET CONSTRAINTS를 넣습니다.

operations = [
    migrations.RunSQL('SET CONSTRAINTS ALL IMMEDIATE;'),
    migrations.RunPython(migration_func),
    migrations.RunSQL('SET CONSTRAINTS ALL DEFERRED;'),
]


답변

열 스키마를 변경하고 있습니다. 해당 바닥 글 열은 더 이상 빈 값을 포함 할 수 없습니다. 해당 열에 대해 DB에 이미 저장된 빈 값이있을 가능성이 높습니다. Django는 migrate 명령을 사용하여 DB의 빈 행을 공백에서 현재 기본값으로 업데이트합니다. Django는 바닥 글 열에 빈 값이있는 행을 업데이트하고 보이는 것과 동시에 스키마를 변경하려고 시도합니다 (확실하지 않습니다).

문제는 동시에 값을 업데이트하려는 동일한 열 스키마를 변경할 수 없다는 것입니다.

한 가지 해결책은 스키마를 업데이트하는 마이그레이션 파일을 삭제하는 것입니다. 그런 다음 스크립트를 실행하여 모든 값을 기본값으로 업데이트하십시오. 그런 다음 마이그레이션을 다시 실행하여 스키마를 업데이트하십시오. 이렇게하면 업데이트가 이미 완료되었습니다. Django 마이그레이션은 스키마 만 변경합니다.


답변