Python Django-DB-Migrations:无法 ALTER TABLE 因为它有挂起的触发事件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12838111/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 11:57:47  来源:igfitidea点击:

Django-DB-Migrations: cannot ALTER TABLE because it has pending trigger events

pythondjangopostgresqldjango-migrations

提问by guettli

I want to remove null=True from a TextField:

我想从 TextField 中删除 null=True:

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

I created a schema migration:

我创建了一个架构迁移:

manage.py schemamigration fooapp --auto

Since some footer columns contain NULLI get this errorif I run the migration:

由于某些页脚列包含NULLerror在运行迁移时得到的信息:

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

django.db.utils.IntegrityError:列“footer”包含空值

I added this to the schema migration:

我将此添加到架构迁移中:

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

Now I get:

现在我得到:

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

What is wrong?

怎么了?

采纳答案by guettli

Every migration is inside a transaction. In PostgreSQL you must not update the table and then alter the table schema in one transaction.

每个迁移都在一个事务中。在 PostgreSQL 中,您不能在一个事务中更新表然后更改表模式。

You need to split the data migration and the schema migration. First create the data migration with this code:

您需要拆分数据迁移和架构迁移。首先使用以下代码创建数据迁移:

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

Then create the schema migration:

然后创建架构迁移:

manage.py schemamigration fooapp --auto

Now you have two transactions and the migration in two steps should work.

现在您有两个事务,分两步进行迁移应该可以工作。

回答by clime

Have just hit this problem. You can also use db.start_transaction() and db.commit_transaction() in the schema migration to separate data changes from schema changes. Probably not so clean as to have a separate data migration but in my case I would need schema, data, and then another schema migration so I decided to do it all at once.

刚遇到这个问题。您还可以在架构迁移中使用 db.start_transaction() 和 db.commit_transaction() 将数据更改与架构更改分开。可能没有单独的数据迁移那么干净,但在我的情况下,我需要架构、数据,然后是另一个架构迁移,所以我决定一次性完成。

回答by maazza

Another reason for this maybe because you try to set a column to NOT NULLwhen it actually already has NULLvalues.

另一个原因可能是因为您尝试将列设置为NOT NULL实际上已经有NULL值的列。

回答by sluge

At the operations I put SET CONSTRAINTS:

在操作中,我设置了 SET CONSTRAINTS:

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

回答by Uzzi Emuchay

You are altering the column schema. That footer column can no longer contain a blank value. There are most likely blank values already stored in the DB for that column. Django is going to update those blank rows in your DB from blank to the now default value with the migrate command. Django tries to update the rows where footer column has a blank value and change the schema at the same time it seems (I'm not sure).

您正在更改列架构。该页脚列不能再包含空白值。该列的数据库中很可能已经存储了空白值。Django 将使用 migrate 命令将数据库中的那些空白行从空白更新为现在的默认值。Django 尝试更新页脚列具有空白值的行并同时更改架构(我不确定)。

The problem is you can't alter the same column schema you are trying to update the values for at the same time.

问题是您无法同时更改尝试更新值的相同列架构。

One solution would be to delete the migrations file updating the schema. Then, run a script to update all those values to your default value. Then re-run the migration to update the schema. This way, the update is already done. Django migration is only altering the schema.

一种解决方案是删除更新架构的迁移文件。然后,运行脚本将所有这些值更新为您的默认值。然后重新运行迁移以更新架构。这样,更新就已经完成了。Django 迁移只是改变了模式。