Django2.2中迁移(makemigrations和migrate)的原理和撤销回退操作图文详解

Django通过ORM来操作数据库,而其中数据库表结构的创建和变更因为尤其重要所以Django需要对其每一次的操作都进行记录和留档,以实现每次只执行增量变更,同时方便回溯和回退。Django中专门负责这一记录功能的模块叫迁移(migrate)。这一篇我们一起来看看迁移的原理和操作步骤,以及出错时的回退。

我是T型人小付,一位坚持终身学习的互联网从业者。喜欢我的博客欢迎在csdn上关注我,如果有问题欢迎在底下的评论区交流,谢谢。

迁移的原理

模型类

所谓ORM就是将面向对象的python操作转变为数据库可识别的SQL语句,而数据库中每张表对应着Django中的一个模型类,也就是在models.py中定义的一个class。所以创建一张张SQL表也就变成了定义一个个模型类,而修改表结构也就变成了修改类属性,这是理解MTV中M,也就是models的核心思想。

例如下面是models.py中定义的三个类,分别是PeopleAmericanChinese。这里的People是另两个的父类,不过这里可以忽略

class People(models.Model):
    p_name = models.CharField(max_length=16)
    p_sex = models.BooleanField(default=True)


class American(People):
    a_state = models.CharField(max_length=16)


class Chinese(People):
    c_province = models.CharField(max_length=16)

完成了ORM映射,就变成了数据库里面的三张表。这里表名带的Four前缀是应用的名字,不用管
1-model.png

增量操作

一个models.py中写着所有的模型类,每一次对单个类做的微小的修改,不可能让所有表都跟着再做一次SQL操作,所以务必得是增量操作。

Django项目里的每一个应用都自带一个migrations目录,每次执行跟表结构变更相关的操作,都会在这里生成增量的操作文件,这些文件叫做迁移文件。

例如上面定义了三个类,在执行生成迁移文件操作之后,新增了下面这个文件
2-migrations.png

文件内容如下

class Migration(migrations.Migration):

    dependencies = [
        ('Four', '0003_auto_20200401_2321'),
    ]

    operations = [
        migrations.CreateModel(
            name='People',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('p_name', models.CharField(max_length=16)),
                ('p_sex', models.BooleanField(default=True)),
            ],
        ),
        migrations.CreateModel(
            name='American',
            fields=[
                ('people_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='Four.People')),
                ('a_state', models.CharField(max_length=16)),
            ],
            bases=('Four.people',),
        ),
        migrations.CreateModel(
            name='Chinese',
            fields=[
                ('people_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='Four.People')),
                ('c_province', models.CharField(max_length=16)),
            ],
            bases=('Four.people',),
        ),
    ]

注意其中的这一部分

dependencies = [
    ('Four', '0003_auto_20200401_2321'),
]

这就是本次执行的上一次执行,也就是说等0003_auto_20200401_2321这个迁移文件中的操作完成以后再执行本文件中的操作。

执行时序

从上面可以看出,migrations目录中的众多迁移文件对应着一批批的操作,这些文件被按照时间顺序先后执行就完成了最终的结果。

那么Django怎么知道某一个文件有没有被执行过呢?

这个也很简单,对每一次完成的操作记录一下时间就可以了。这些操作都被记录在项目自带的django_migrations表中。打开django_migrations表看一下
3-table.png
可以看到对于应用Four一共执行过四次操作,最后一次操作就是我们刚才创建三个表的0004_american_chinese_people文件。

迁移的步骤

有了上面的原理做为铺垫,梳理出迁移的操作步骤就不难了。

  1. 首先在models.py中创建或者修改模型类
  2. python manager.py makemigrations创建本次修改的迁移文件,此时会去数据库中查找上一次执行的文件并记录在本文件中
  3. 然后执行python manager.py migrate执行迁移,将变更同步到数据库中

迁移的回退

假如某次操作涉及的操作太细碎,迁移后的效果不理想,最好的办法就是回退到上一次迁移的时候。

Django为我们创建了快捷的回退操作,直接对前一步的迁移文件重新手动迁移一次即可完成回退操作。

以上面创建三个表为例,直接再跑python manage.py migrate Four 0003_auto_20200401_2321即可。记得带上Four这个应用名

[fuhx@testmachine DjangoModel]$ python manage.py migrate Four 0003_auto_20200401_2321
Operations to perform:
  Target specific migration: 0003_auto_20200401_2321, from Four
Running migrations:
  Rendering model states... DONE
  Unapplying Four.0004_american_chinese_people... OK

之后会发现数据库中的三张表被自动删除了,同时django_migrations表中最后一条记录也没了
4-fallback.png

之后别忘了手动删除migrations目录中的0004号迁移文件,从而完成回退动作。

makemigrations和migrateDjango的两个相关但不同的命令。makemigrations命令用于创建数据库迁移文件,当你在Django修改了模型的结构时,需要运行makemigrations命令来生成一个包含这些修改的迁移文件。迁移文件包含了数据库模式的变化,包括创建、修改或删除表、添加或删除字段等。而migrate命令用于执行数据库迁移,即将模型的变化应用到数据库的过程。当你运行migrate命令时,Django会检查迁移文件,并将其的变化应用到数据库,确保数据库的结构与模型的结构保持一致。简而言之,makemigrations用于生成数据库迁移文件,而migrate用于将迁移文件应用到数据库makemigrations是一个生成迁移文件的过程,而migrate是一个执行迁移文件的过程。如果想指定某个migrations文件,可以使用命令python manage.py migrate \[app_label\] \[migration_name\],例如python manage.py migrate cases 0011_auto_20220726_1440。\[2\]\[3\] #### 引用[.reference_title] - *1* *3* [DjangoMigrateMakemigrations讲解](https://blog.csdn.net/momoda118/article/details/120181669)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [djangomigratemakemigrations 区别](https://blog.csdn.net/yuanhou110/article/details/131455342)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值