实践 Django App Model 和数据库的迁移

良好的重构是项目可持续的一个重要因素。最近开始花时间重构「奇点」的网站部分,其中一个任务就是把 Django 项目的 Model 以及数据库进行迁移和合并,今天实践了一把,很成功,写文章纪录一下。

什么是「App Model 迁移」,简单地说,一个 Django 项目可能存在不同的 App,随着项目的发展,或者早先错误的规划,需要重新调整一下项目结构,比如把 App 们合并起来,把 App B 的东西合并至 App A,这就涉及到了 Model 和数据库的迁移。

如何进行无痛的 App Model 迁移呢?涉及到代码层面的可能还比较方便,但是已经存在的数据如何用正确地方式去迁移,这就是一个问题了。在参考了 StackoverFlow 上的一个回答后(How to move a model between two Django apps),我成功地在我的 Django 2.0 项目上完成了 Model 和已有数据的迁移。

先来看看操作前的 PostgreSQL 的数据表结构,除去 Django 内置的 Model,你可以从这个数据表结构里看到,我有两个 Django App,分别是 jidian 和 weibo。我要做的事情就是,在 Django 项目结构上,把 weibo 的代码合并进 jidian,同时把数据库也做相应的变化。

Move Django App Model 01

根据 How to move a model between two Django apps 这个答案,一步步操作下来,就可以顺利完成。

第一步:手动创建 weibo 至 jidian 的 Migration

在终端执行,手动创建一个 weibo 的 migration,这一步操作的意思是,把 weibo 的数据库结构修改成以 jidian 为名的。

python manage.py makemigrations weibo --empty

源码:

# Generated by Django 2.0.4 on 2018-04-12 03:06

from django.db import migrations


class Migration(migrations.Migration):

    dependencies = [
        ('weibo', '0007_weibouser_task_schedule_date'),
    ]

    database_operations = [
        migrations.AlterModelTable('Subscription', 'jidian_subscription'),
        migrations.AlterModelTable('WeiboStatus', 'jidian_weibostatus'),
        migrations.AlterModelTable('WeiboUser', 'jidian_weibouser')
    ]

    state_operations = [
        migrations.DeleteModel('Subscription'),
        migrations.DeleteModel('WeiboStatus'),
        migrations.DeleteModel('WeiboUser')
    ]

    operations = [
        migrations.SeparateDatabaseAndState(
            database_operations=database_operations,
            state_operations=state_operations)
    ]

第二步: jidian 接收来自 weibo 的 Migration

在 jidian 这个 App 里,创建好和 weibo 里一模一样的 Model,准备好接收(注意这会不要删除 weibo 的东西,也不要从 INSTALLED_APPS 里移掉它。

创建好文件后, 终端运行以下指令,会自动生成一个待接受的 migration:

python manage.py makemigrations jidian

然后,对自动生成的 Migration 稍作修改,把 operations 改成 state_operations,并增加一个真正的 operations。

operations = [
        migrations.SeparateDatabaseAndState(state_operations=state_operations)
    ]

关于这些操作的真正含义,可以见文档,我也是一知半解,所以就不多说了:https://docs.djangoproject.com/zh-hans/2.0/ref/migration-operations/

第三步:Do Migration

所有的东西都 Ready 了,这时开始真正的 Migration 步骤:

python manager.py migrate

如果一切正常的话,这个时候数据表就会成功修改,App 和 Model 也将工作一致。成功地把两个 App 合并起来了:

Move Django App Model 02

总结

借用 Web 框架自带的机制去做这个操作,不要手动去改数据库文件,可以自动化检查,并且保证所有的东西仍然继续工作。

欢迎使用图拉鼎开发的产品

Manico - 快速启动和切换 App

高效率 App 启动与切换工具,使用它将加倍电脑日常使用的效率,免费下载体验。

No Comment

Leave a Comment