gue*_*tli 103 python django postgresql django-migrations
我想从TextField中删除null = True:
- footer=models.TextField(null=True, blank=True)
+ footer=models.TextField(blank=True, default='')
Run Code Online (Sandbox Code Playgroud)
我创建了一个模式迁移:
manage.py schemamigration fooapp --auto
Run Code Online (Sandbox Code Playgroud)
由于一些页脚列包含NULL
我得到这个,error
如果我运行迁移:
django.db.utils.IntegrityError:列"footer"包含空值
我将此添加到架构迁移中:
for sender in orm['fooapp.EmailSender'].objects.filter(footer=None):
sender.footer=''
sender.save()
Run Code Online (Sandbox Code Playgroud)
现在我得到:
django.db.utils.DatabaseError: cannot ALTER TABLE "fooapp_emailsender" because it has pending trigger events
Run Code Online (Sandbox Code Playgroud)
怎么了?
maa*_*zza 122
另一个原因可能是因为您尝试将列设置为NOT NULL
实际已有NULL
值的列.
gue*_*tli 114
每次迁移都在交易中.在PostgreSQL中,您不能更新表,然后在一个事务中更改表模式.
您需要拆分数据迁移和架构迁移.首先使用以下代码创建数据迁移:
for sender in orm['fooapp.EmailSender'].objects.filter(footer=None):
sender.footer=''
sender.save()
Run Code Online (Sandbox Code Playgroud)
然后创建架构迁移:
manage.py schemamigration fooapp --auto
Run Code Online (Sandbox Code Playgroud)
现在您有两个事务,并且两个步骤中的迁移应该有效.
slu*_*uge 19
在操作中,我设置了 SET CONSTRAINTS:
operations = [
migrations.RunSQL('SET CONSTRAINTS ALL IMMEDIATE;'),
migrations.RunPython(migration_func),
migrations.RunSQL('SET CONSTRAINTS ALL DEFERRED;'),
]
Run Code Online (Sandbox Code Playgroud)
Zag*_*ags 12
如果要添加不可为空的字段,则需要分两次迁移:
AddField
并RunPython
填充它AlterField
将字段更改为不可为空在 PostgreSQL 和 SQLite 上,如果您有一个足够复杂的RunPython
命令并在同一迁移中结合了架构更改,则可能会出现此问题。例如,如果您要添加一个不可为空的字段,那么典型的迁移步骤是:
AddField
将该字段添加为可为空RunRython
填充它AlterField
将字段更改为不可为空在 SQLite 和 Postgres 上,这可能会导致问题,因为整个事情都在一个事务中完成。
在Django文档对此有一个特定的警告:
在支持 DDL 事务(SQLite 和 PostgreSQL)的数据库上,除了为每次迁移创建的事务之外,RunPython 操作不会自动添加任何事务。因此,例如,在 PostgreSQL 上,您应该避免在同一迁移中组合模式更改和 RunPython 操作,否则您可能会遇到类似 OperationalError: cannot ALTER TABLE "mytable" 因为它具有挂起的触发事件的错误。
如果是这种情况,解决方案是将您的迁移分成多个迁移。一般来说,拆分的方法是让第一次迁移包含通过 run_python 命令向上的步骤,第二次迁移包含它之后的所有步骤。因此,在上述情况下,模式将是AddField
和RunPython
在一次迁移中,AlterField
在第二次迁移中。
刚刚遇到这个问题.您还可以在架构迁移中使用db.start_transaction()和db.commit_transaction()将数据更改与架构更改分开.可能不是那么干净,没有单独的数据迁移,但在我的情况下,我需要架构,数据,然后另一个架构迁移,所以我决定一次完成所有这一切.
归档时间: |
|
查看次数: |
35496 次 |
最近记录: |