【问题标题】:Renaming Django model without breaking existing migrations在不破坏现有迁移的情况下重命名 Django 模型
【发布时间】:2021-10-12 03:53:20
【问题描述】:

我想在 Django 3.2 中重命名一个模型,保留我现有的迁移,并且能够迁移具有旧表名的数据库并从头开始创建一个数据库。

我首先重命名了模型类以及代码中对它的所有引用。由于“./manage.py makemigrations”没有自动创建迁移,我手动创建了一个重命名模型的迁移:

from django.db import migrations

class Migration(migrations.Migration):

    dependencies = [
        ('market_integrations', '0003_migration'),
    ]

    operations = [
        migrations.RenameModel('OldModelName', 'NewModelname')
    ]

我最初的想法是我不应该更新现有的迁移,因为我在创建其他迁移时从不这样做。但是,当我运行“./manage.py migrate”时,旧迁移中对旧模型的引用会导致 LookupError。我已经尝试使用模型名称字符串和apps.get_model()。失败的迁移代码示例:

operations = [
    migrations.CreateModel(
        name="OldModelName",
    ...
    )
]


operations = [
    migrations.CreateModel(
        name=apps.get_model("myapp", "OldModelName"),
    ...
    )
]

由于在旧迁移中保留旧模型名称不起作用,我将旧迁移中的旧模型名称替换为新名称。之后,“./manage.py migrate”运行成功,包括模型重命名迁移。但是,当我尝试创建新数据库时,模型重命名迁移失败,因为该新数据库从来没有使用旧名称的表。

我应该怎么做才能保留我的迁移并让它们在现有和新数据库中工作?

我已经检查了Django migration strategy for renaming a model and relationship fields,但我没有在那里找到我的问题的答案。

【问题讨论】:

    标签: django django-migrations


    【解决方案1】:

    请附上完整的模型(您可以删除不相关的字段)和您在初始问题中创建的迁移(我还不能评论您的初始帖子,所以我必须在答案中提及)。

    这很重要,因为我认为有外键指向您要重命名的模型。 或者您是否尝试将 Foo 重命名为 Bar 并创建一个 new Foo?

    如果您在最初的想法之后尝试启动服务器,是否也会出现错误? 您保持现有迁移不变的最初想法似乎很好,因为您将能够在所有环境(本地、开发、生产等)上运行它,并且方法 2 需要手动重命名数据库表和字段。

    在您提供模型和迁移后,我也许可以扩展我的答案。

        migrations.RenameModel(
            old_name="ModelA",
            new_name="ModelB",
        ),
    
        migrations.AlterField(
            model_name="myrelatedmodel",
            name="somefieldname",
            field=models.ForeignKey(
                # change the properties accordingly (best copy it over). The database may only change to="table"
                null=True,
                on_delete=django.db.models.deletion.SET_NULL,
                to="myapp.modelb",
            ),
        ),
    

    如果这不起作用,错误来自哪里?您可以尝试将您的迁移和模型与其余代码隔离开来(例如在附加到同一数据库的新空项目中)。也许这将帮助您找出错误是来自对 OldModelName 的剩余引用还是一些奇怪的错误。就像一个想法,这样您就不会花时间看错误的地方

    尝试一次进行一项更改和一项迁移。您可以稍后将它们压扁。如果 django 没有自动检测模型的重命名,则意味着与该模型相关的所有字段也会失败。

    1. 在重命名之前将所有内容恢复到工作状态
    2. 确保应用所有迁移
    3. 重命名模型并创建迁移以仅重命名模型。你能申请吗?
    4. 如果没有,请尝试手动修改所有相关字段(one2one、foreignkey 等)

    如果仍然失败,请在 models.py 中创建模型的副本,重命名复制的模型并尝试在新的迁移文件中使用 migrations.RunPython() 将旧表中的所有数据复制到新表中。

    如果您只有一个填充的数据库,您可能会用 ModelB 替换所有出现的 ModelA 并更改数据库的结构。

    祝你好运!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-29
      • 2014-09-15
      • 1970-01-01
      • 2015-05-02
      • 1970-01-01
      • 2017-05-19
      相关资源
      最近更新 更多