首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Revert 1.7 RemoveField迁移

Revert 1.7 RemoveField迁移
EN

Stack Overflow用户
提问于 2015-03-05 12:58:07
回答 4查看 6.7K关注 0票数 34

如果我有一个不可空的模型字段,删除它并创建一个迁移,该迁移就变得不可逆了:

考虑以下模式:

代码语言:javascript
复制
class Foo(models.Model):
    bar = models.TextField()
    test = models.TextField()  # This field is to go away, bye-bye!

和移徙问题:

代码语言:javascript
复制
# app/migrations/003_remove_foo_test.py

class Migration(migrations.Migration):

    dependencies = [
        ('app', '0002_foo_test'),
    ]

    operations = [
        migrations.RemoveField(
            model_name='foo',
            name='test',
        ),
    ]

不应用此迁移会引发异常:

代码语言:javascript
复制
$ src/manage.py migrate app 0002
Operations to perform:
  Target specific migration: 0002_foo_test, from app
Running migrations:
  Unapplying app.0003_remove_foo_test...Traceback (most recent call last):
...
django.db.utils.IntegrityError: column "test" contains null values

当然,这是预期的行为,是清楚地记录,我不是在问为什么会发生这种情况:

请记住,当反转时,这实际上是向模型中添加一个字段;如果该字段不可为空,则可能使此操作不可逆转(除了任何数据丢失外,这当然是不可逆转的)。

然而,我们都会犯错误,有时我们只需要以某种方式逆转字段删除,即使这意味着手动为所有反向非空字段提供一个临时存根值。例如,南方迁移允许这种操作的逆转(询问开发人员是为恢复的字段提供默认的,还是不允许反向迁移),这似乎并不适用于所有新的、花哨的Django 1.7迁移。

问题:使用Django 1.7+迁移(假设已经发生)撤消字段删除的最简单/最快的方法是什么?它不一定需要完全用编写脚本,一组手动指令就可以了。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-03-05 13:31:52

您可以手动编辑迁移,并为AlterField之前的字段添加默认值。即使在移民之后,也应该是安全的。这将使RemoveField后发生的是可逆的。

举个例子。在模型summary中具有名为profit的字段,该字段是在删除之前定义的:

代码语言:javascript
复制
profit = models.PositiveIntegerField(verbose_name='profits')

您应该在它的RemoveField之前添加一个这样的AlterField

代码语言:javascript
复制
migrations.AlterField(
    model_name='summary',
    name='profit',
    field=models.PositiveIntegerField(verbose_name='profits', default=0),
    preserve_default=False,
    ),
票数 29
EN

Stack Overflow用户

发布于 2015-03-05 13:10:40

如果您试图使将来的迁移可逆,您可以尝试将该字段移除为三个迁移。

  1. 使字段为空
  2. 数据迁移。向前,什么都别做。向后,将空转换为存根值。
  3. 移除字段

这三个步骤中的每一个都应该是可逆的。

如果您已经运行了迁移并需要将其反转,则可以

  1. 手动添加字段,允许为空
  2. 将空值转换为存根值
  3. 手动添加null约束
  4. 使用--fake迁移到以前的迁移
票数 5
EN

Stack Overflow用户

发布于 2020-06-19 10:42:05

最简单的方法可能是使用migrations.RunSQL

您可以编辑迁移,以便您的operations列表如下所示:

代码语言:javascript
复制
operations = [
    sql=[('alter table foo_test drop test)],
    reverse_sql=[('alter table foo_test add test varchar)]
]

这将是一个令人讨厌的解决方案,但也可能是任何其他解决方案。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28878428

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档