django orm插入一条_Django的使用及原理介绍[2]migration的机制和原理

1

概述

前文"django的使用及原理介绍[1]-初始Django"中介绍了如何使用Django搭建一个数据库管理的应用。其中介绍了如何通过model创建表/表字段,如何通过api添加/更新下删除表记录,在这个过程中,全程没有介绍任何关于mysql的操作。能让Django对数据库表进行管理而不需要写一行mysql语句,最大的功臣就是ORM(Object Relational Mapping, 对象管理映射)。本文结合ORM介绍migration的机制和原理。

2ORM是什么

在大学学编程时老师提到最多的就是要面向对象编程(Object Oriented Programming, OOP),面向对象编程是一种程序设计思想,其将所有的实体作为对象,一个对象包含了数据和对数据的操作(函数)。当前最流行的是关系型数据库,关系型数据库包括实体及实体之间的关系,实体之间的关系也可以使用对象进行表达,这样就将关系型数据库与面向对象编程的对象有了一一对应的关系。而ORM 就是通过实例对象的语法,完成关系型数据库的操作的技术。ORM将数据库映射成对象的关系如下:

  • 数据库的表(table) --> 类(class)

  • 记录(record,行数据)--> 对象(object)

  • 字段(field)--> 对象的属性(attribute)

数据库的操作则映射为类方法,由类方法完成数据库的CRUD操作。正式因为ORM使用对象封装了数据库的所有操作,因此可以无需使用任何的SQL语句只需使用面向对象编程,完成与数据对象的交互。总结起来ORM的优点包括:

  • 数据模型统一集中定义,更加容易更新和维护,也利于重用代码

  • 开发是面向对象的,有利于提高开发效率,降低开发成本。

  • 很多框架提供了现成ORM,很多功能能够直接使用。

  • ORM是基于MVC架构的,按该架构开发会使代码更清晰。

  • 降低了对SQL的使用门槛,避免编写性能不佳的SQL。

当然ORM也有缺点:

  • 对象到关系型数据库的映射需要消耗系统性能,性能不如原生SQL。

  • 在多表查询时,会使ORM变得很复杂。

  • ORM抽象了数据库层,开发者无法定制一些特殊的SQL操作。

但整体而言,使用ORM机制在实际的开发中,会大大提升开发的效率,缩短开发周期,因此也受到广大开发的青睐。

3 Django的migration过程 在前面分享的文章"django的使用及原理介绍[1]-初始Django"中,在启动服务之前需要执行如下命令:
python manage.py makemigrations bm  # 在bm模块下生成migrations文件夹,包含0001_initial.py文件。python manage.py migrate bm   # 将0001_initial.py的变更更新到数据库中。

这两条命令就是将在bm/models.py中定义的对象映射到数据库表。在bm/models.py中定义的类(Class)对应数据库中的表(Table)。这里以Title类(表)为例介绍,models.py中Title类定义如下:

class Title(models.Model):    STATUS_ENABLED = 0    STAUS_DISABLED = 1    STATUS_CHOICE = (        (STATUS_ENABLED, 'enabled'),        (STAUS_DISABLED, 'disabled')    )    name = models.CharField(max_length=128, verbose_name='title')    created_at = models.DateTimeField(auto_now_add=True)    updated_at = models.DateTimeField(auto_now=True)    status = models.SmallIntegerField(choices=STATUS_CHOICE, default=STATUS_ENABLED)

执行“python manage.py makemigrations bm”后会将应用下models.py中的类(继承了django.db.models.Model)生成对应的migrations文件,若是第一次执行,则会在bm/migrations下生成0001_initial.py文件,如下:    

7e4d4178f4b42112f2da27930093690b.png 0001_initial.py中生成的Title相关内容如下:
class Migration(migrations.Migration):    initial = True    dependencies = []    operations = [        migrations.CreateModel(            name='Title',            fields=[                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),                ('created_at', models.DateTimeField(auto_now_add=True)),                ('updated_at', models.DateTimeField(auto_now=True)),                ('status', models.SmallIntegerField(choices=[(0, 'enabled'), (1, 'disabled')], default=0)),                ('name', models.CharField(max_length=128, verbose_name='title')),            ],            options={                'ordering': ('created_at',),            },        )    ]
若类Title中没有定义id属性,则生成的migrations文件会自动添加id字段,默认是int型,若定义了id属性,则优先使用用户定义的id字段,可以将id定义为uuid类型( id = models.UUIDField() )。若是已经生成了 0001_initial.py文件,然后对Title进行变更,比如增加desc字段,如下:
class Title(models.Model):    STATUS_ENABLED = 0    STAUS_DISABLED = 1    STATUS_CHOICE = (        (STATUS_ENABLED, 'enabled'),        (STAUS_DISABLED, 'disabled')    )    name = models.CharField(max_length=128, verbose_name='title')    created_at = models.DateTimeField(auto_now_add=True)    updated_at = models.DateTimeField(auto_now=True)    status = models.SmallIntegerField(choices=STATUS_CHOICE, default=STATUS_ENABLED)    desc = models.CharField(max_length=512)   # 增加的字段
再次执行“ python manage.py makemigrations bm ”则会在0001_initial.py 生成新了migrations文件。       41cf2b44fb7932966cd2aef074073173.png

生成的0002_title_desc.py文件的内容如下:

class Migration(migrations.Migration):    dependencies = [        ('bm', '0001_initial'),    ]    operations = [        migrations.AddField(            model_name='title',            name='desc',            field=models.CharField(default='', max_length=512),        ),    ]

0002_title_desc.py中的dependencies指明了依赖的前一个migrations文件(例子中是0001_initial.py),所以0002_title_desc.py记录的是相对于前一个migrations文件的变化。

执行完“python manage.py makemigrations bm”,然后执行“python manage.py migrate bm”,将会将migrations的变更在数据库中执行(新建表或增加/删除字段等)。

4

Django的migration原理

models.py的变更最终会作用到数据库中,其映射关系如下:

c505c4b4480c2f22d5c627c4c874ab01.png

在models.py中可做的修改包括新建类(表)、增加字段、删除字段及变更字段的属性,需要注意的是:a) 新增表字段和删除表字段不要同时做,否则django会解析为将删除的字段修改为新增的字段,可能会导致字段属性不一致等问题(表中删除字段数据格式与新增字段格式不一致);b)一般而言,不表进行删除字段操作,只做新增操作。

执行“python manage.py makemigrations”过程,主要工作是根据models.py的变更和已经生成的migrations文件进行比较,来生成变更的migrations文件。

执行“python manage.py migrate”过程,为了保证执行的migrations文件不重复执行(重复执行会有问题),因此django在每个应用下还会额外自动创建django_migration表,用于记录执行过的migrations文件,如示例中的bm数据库包括的表为(bm_author, bm_book,bm_title为models.py定义的,django_migration为django自动创建的):

c93a54da4b251c7b3c2aa36632560c51.png    

在修改models.py之前,可以看到django_migration表中的数据为:

22cd586f81d043fe6922a0a008514760.png

修改models.py(为Title类增加desc字段),执行“python manage.py migrate”后,会在表中增加一条数据,如下:

bd21e5d7f77695d2a7d2fba4022d668d.png 5总结

本文介绍了models.py的变更如何作用到数据库中,演示采用的是sqlite数据库,实际使用时也可以在settings.py文件中配置其他数据库。后文将会介绍rest_framework的源码,django的执行过程等。示例代码见:https://github.com/836304831/mp_weixin.git。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值