Django 1.8:删除/重命名数据迁移中的模型字段

Posted

技术标签:

【中文标题】Django 1.8:删除/重命名数据迁移中的模型字段【英文标题】:Django 1.8: Delete/rename a model field in data migration 【发布时间】:2015-10-12 10:52:17 【问题描述】:

我需要将模型字段的关系从 ForeignKey 更改为 ManyToManyField。这附带数据迁移,以更新预先存在的数据。

以下是原始模型(models.py):

class DealBase(models.Model):

    [...]
    categoria = models.ForeignKey('Categoria')
    [...]

    )

我需要模型字段“类别”与应用“交易”中的模型“类别”建立多对多关系。

我做了什么:

    在 DealBase 中创建一个新字段 'categoria_tmp'

    class DealBase(models.Model):
         categoria = models.ForeignKey('Categoria')
         categoria_tmp = models.ManyToManyField('Categoria',related_name='categoria-temp')
    

    进行架构迁移

    python manage.py makemigrations

    编辑 migrationfile.py 以将数据从 categoria 迁移到 categoria-tmp

    def copy_deal_to_dealtmp(apps, schema_editor):
        DealBase = apps.get_model('deal', 'DealBase')
    
        for deal in DealBase.objects.all():
            deal.categoria_tmp.add(deal.categoria)
            deal.save()
    
    class Migration(migrations.Migration):
    
        dependencies = [
          ('deal', '0017_dealbase_indirizzo'),
        ]
    
        operations = [
           migrations.AddField(
           model_name='dealbase',
           name='categoria_tmp',
           field=models.ManyToManyField(related_name='categoria-temp', to='deal.Categoria'),
           preserve_default=True,
          ),
    
           migrations.RunPython(
            copy_deal_to_dealtmp
           )
          ]
    

    进行数据迁移

    python manage.py 迁移

    最后我需要删除“dealbase.categoria”列并将“dealbase.categoria-tmp”列重命名为“dealbase.categoria”

我卡在第 5 步。

有人可以帮我吗?我在网上找不到答案,我使用的是 Django 1.8。

谢谢!

【问题讨论】:

尝试从您的模型中删除 dealbase.categoria 并创建一个应该删除该字段的迁移,然后将 categoria-tmp 重命名为 categoria 并创建另一个我认为应该只更改该字段的迁移 是的,它成功了!谢谢 太棒了,现在给它一个答案:) 【参考方案1】:

您只需要创建两个额外的迁移:一个用于删除旧字段,另一个用于更改新字段。

首先删除 dealbase.categoria 并创建一个迁移,然后将 dealbase.categoria-tmp 重命名为 dealbase.categoria 并创建另一个迁移。

这将删除第一个字段,然后将 tmp 字段更改为正确的名称。

【讨论】:

Django 是否按顺序(顺序)执行操作?【参考方案2】:

试试这个,可能对你有帮助。

    第一步是你的

    python manage.py makemigrations && python manage.py migrate
    

    打开shell

    for i in DealBase.objects.all()
        i.categoria_tmp.add(i.categoria)
    

    删除您的字段categoria

    python manage.py makemigrations && python manage.py migrate
    

    添加字段

    categoria = models.ManyToManyField('Categoria',related_name='categoria-temp')
    

    然后

    python manage.py makemigrations && python manage.py migrate
    

    打开shell

    for i in DealBase.objects.all():
        for j in i.categoria_tmp.all():
            i.categoria.add(j)
    

    删除字段categoria_tmp

    python manage.py makemigrations && python manage.py migrate
    

【讨论】:

感谢您的回答。我按照 Jeff_Hd 的建议做了,它奏效了。我确定您的解决方案也是有效的。如果@Jeff_Hd 没有从他的评论中做出回答,我会将“已解决”给你。 不,请接受解决您问题的答案。我完全不确定这是最佳答案。如果 Jeff_Hd 的答案解决了您的问题,请接受。 对于任何阅读此答案的人:步骤 2 和 5 完全错误,您需要数据迁移。【参考方案3】:

如果您在此模型中没有任何数据,只需对该模型进行注释,然后运行 ​​manage.py makemigrations 并迁移。然后删除错误的字段并删除注释代码,并制作makemigrationsmigrate。这也适用于 Django 2。

【讨论】:

以上是关于Django 1.8:删除/重命名数据迁移中的模型字段的主要内容,如果未能解决你的问题,请参考以下文章

在 Django 中重命名模型(表)

在不破坏现有迁移的情况下重命名 Django 模型

Django 1.8:删除迁移文件夹后未检测到迁移

如何重命名 Django 应用程序并将数据从一个应用程序迁移到另一个应用程序

如何在 django (1.8) 迁移中删除索引 varchar_pattern_ops?

在 django 1.8 中将数据从原始用户模型迁移到自定义用户模型