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 마이그레이션은 스키마 만 변경합니다.