Shr*_*yas 28 python database django-models schema-migration
这是这个问题的扩展:如何在两个Django应用程序之间移动模型(Django 1.7)
我需要将一堆模型从中移动old_app
到new_app
.最好的答案似乎是Ozan的,但是需要外键引用,事情有点棘手.@halfnibble在对Ozan的答案的评论中提出了一个解决方案,但我仍然遇到了精确的步骤顺序问题(例如,何时将模型复制到new_app
,何时删除模型old_app
,哪些迁移将在old_app.migrations
vs中进行.new_app.migrations
等)
任何帮助深表感谢!
Nos*_*.io 70
在应用之间迁移模型.
简短的回答是,不要这样做!!
但这个答案很少适用于生活项目和生产数据库的现实世界.因此,我创建了一个示例GitHub repo来演示这个相当复杂的过程.
我正在使用MySQL.(不,那些不是我真正的凭据).
问题
我正在使用的示例是一个带有汽车应用程序的工厂项目,该应用程序最初具有Car
模型和Tires
模型.
factory
|_ cars
|_ Car
|_ Tires
Run Code Online (Sandbox Code Playgroud)
该Car
模型与ForeignKey有关系Tires
.(如同,通过汽车模型指定轮胎).
但是,我们很快意识到这Tires
将是一个拥有自己的视图等的大型模型,因此我们希望它在自己的应用程序中.因此,所需的结构是:
factory
|_ cars
|_ Car
|_ tires
|_ Tires
Run Code Online (Sandbox Code Playgroud)
我们需要保持ForeignKey之间的关系Car
,Tires
因为太多依赖于保留数据.
解决方案
步骤1.设置设计错误的初始应用程序.
步骤2.创建管理界面并添加一堆包含ForeignKey关系的数据.
查看第2步.
步骤3.决定将Tires
模型移动到自己的应用程序.精心剪切并粘贴代码到新轮胎应用程序中.确保更新Car
模型以指向新tires.Tires
模型.
然后./manage.py makemigrations
在某个地方运行并备份数据库(以防这种情况严重失败).
最后,运行./manage.py migrate
并查看厄运的错误消息,
django.db.utils.IntegrityError:(1217,'无法删除或更新父行:外键约束失败')
第4步.棘手的部分.自动生成的迁移无法看到您只是将模型复制到其他应用程序.所以,我们必须做一些事情来解决这个问题.
您可以跟随并查看步骤4中的注释的最终迁移.我测试了这个以验证它是否有效.
首先,我们将继续努力cars
.您必须进行新的空迁移.实际上,此迁移需要在最近创建的迁移(无法执行的迁移)之前运行.因此,我重新编号了我创建的迁移并更改了依赖项以首先运行我的自定义迁移,然后是cars
应用程序的上次自动生成的迁移.
您可以使用以下命令创建空迁移:
./manage.py makemigrations --empty cars
Run Code Online (Sandbox Code Playgroud)
步骤4.a. 进行自定义old_app迁移.
在第一次自定义迁移中,我只会执行"database_operations"迁移.Django为您提供了拆分"状态"和"数据库"操作的选项.您可以在此处查看代码,了解如何完成此操作.
我在第一步的目标是重命名数据库表,oldapp_model
而newapp_model
不是搞乱Django的状态.您必须根据应用程序名称和型号名称弄清楚Django将您的数据库表命名为什么.
现在您已准备好修改初始tires
迁移.
步骤4.b. 修改new_app初始迁移
操作很好,但我们只想修改"状态"而不是数据库.为什么?因为我们从cars
应用程序中保留数据库表.此外,您需要确保先前进行的自定义迁移是此迁移的依赖项.查看轮胎迁移文件.
所以,现在我们已经更名cars.Tires
到tires.Tires
数据库中,并改变了Django的状态识别tires.Tires
表.
步骤4.c. 修改old_app上次自动生成的迁移.
去背到汽车,我们需要修改最后自动生成的迁移.它应该需要我们的第一次定制汽车迁移,以及最初的轮胎迁移(我们刚刚修改过).
这里我们应该离开AlterField
操作,因为Car
模型指向不同的模型(即使它具有相同的数据).但是,DeleteModel
由于cars.Tires
模型不再存在,我们需要删除有关的迁移线.它已完全转换为tires.Tires
.查看此迁移.
步骤4.d. 清理old_app中的陈旧模型.
最后但同样重要的是,您需要在汽车应用中进行最终的自定义迁移.在这里,我们将仅执行"状态"操作以删除cars.Tires
模型.它是仅状态的,因为cars.Tires
已重命名数据库表.这最后的迁移清理剩余的Django的状态.
归档时间: |
|
查看次数: |
6634 次 |
最近记录: |