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

Posted

技术标签:

【中文标题】如何重命名 Django 应用程序并将数据从一个应用程序迁移到另一个应用程序【英文标题】:How to rename a Django app and migrate data from an app to the other 【发布时间】:2017-12-10 22:46:00 【问题描述】:

我有一个名为 app1 的 Django 应用程序,其中包含模型和迁移文件。 我将此应用程序重命名为app2,并修复了所有导入、url 等... 我现在遇到了迁移文件和表格中的数据问题。

我怎样才能用正确的方式编写迁移以确保:

全新安装 => 创建新表 更新旧版本 => 创建新表、移动数据、删除旧表

注意 1:有几个表有很多外键。

这是我到目前为止的进步,我不确定我是否在好的路上:

我删除了所有旧迁移 我运行 python manage.py makemigrations 来生成新的迁移文件

完成这两个步骤后,我可以安装我的应用程序,但我仍然遇到旧版本的问题。

问题:迁移数据的最佳方式是什么?

注意 2:我不使用South

【问题讨论】:

【参考方案1】:

重命名应用程序总是一个棘手的问题。

如果您像简单的表重命名迁移一样进行迁移,则旧应用的 apps.get_model() 随时都无法工作,因为该应用根本不存在。

我找到了this answer。我知道您没有使用南,但我认为它可能会以相同的方式工作,只需跳过南步骤。

基本上,您必须:

    在重命名之前将数据转储到 json 文件

    运行答案中的脚本,将 json 文件中的引用从 app1 重命名为 app2

    app1 重命名为 app2 (所有导入引用,settings.py 等)

    运行迁移以创建 app2 的表

    json文件中的数据加载到数据库

    删除app1

希望对你有所帮助。

【讨论】:

【参考方案2】:

我找到了一个可行的解决方案

    使用新的外键和新的应用依赖项修复旧迁移。 强制旧迁移使用旧应用名称创建表,因此在migrations.CreateModel.options 中添加db_table: 'app1_table_name' 在每个迁移文件中添加replaces = [('app1', 'migration_file_name')]。这将告诉 Django 当前迁移 (app2.migration_file_name) 将替换旧文件,这将防止 django 执行两次迁移。 创建迁移文件以使用migrations.AlterModelTable 重命名表

【讨论】:

补充一点,我发现django在使用这种方法重命名应用程序时不会更新内容类型,而是会为每个应用程序模型创建新的内容类型(和权限)。迁移运行。如果您使用通用外键等,这将导致麻烦。我通过在所有AlterModelTables 之前添加RunPython 操作来解决此问题。我的RunPython 函数运行ContentType = apps.get_model('contenttypes', 'ContentType') ContentType.objects.filter(app_label='old_app').update(app_label='new_app') 这太棒了!要想弄清楚我们很少使用的所有这些东西的详细路径,需要花费大量时间。 这真的很有用,我什至都不知道在文档中寻找这些东西。【参考方案3】:

这在blog post中得到了雄辩的回答。

要点是:

    重命名您要更新的应用程序的文件夹。 更新任何和导入语句到您更新的文件夹。 更新django_content_type 表的条目以引用应用程序的app_label。 更新您尚未明确设置表名的任何模型的表名。这些表名由应用程序名称推断,需要更新。 更新 django_migrations 表的条目,并通过将应用字段设置为新应用标签来更新每次迁移的参考。 更新/static/templates 文件夹中的所有命名空间文件夹名称。例如,您可能有 ./foo_app/templates/foo_app/index.html,应该更新为./bar_app/templates/bar_app/index.html

【讨论】:

以上是关于如何重命名 Django 应用程序并将数据从一个应用程序迁移到另一个应用程序的主要内容,如果未能解决你的问题,请参考以下文章

如何从默认 Django 模型重命名模型字段?

在 Oozie 或 pig 运行时重命名文件夹

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

django如何给上传的图片重命名(给上传文件重命名)

如何在 ruby​​ 中使用 MongoMapper 重命名数据库?

django:如何在管理面板中重命名记录