当前位置: 首页 > 后端技术 > Python

Django笔记二十:手动编写迁移文件

时间:2023-03-25 23:03:04 Python

前面提到,迁移文件主要是记录Django系统模型的变化,然后通过migrate命令将变化适配到数据库中。比如某个应用下新增了一个表,或者某个表的某个字段发生了变化,可以生成一个迁移文件,然后通过migrate更改到数据库中。除了系统自动生成,我们还可以手动创建迁移文件来操作数据库。这个用途主要用在,比如建表后需要写入一些初始数据的时候。基本命令迁移文件介绍自定义迁移文件RunSQL()RunPython()1.基本命令关于迁移命令如下:makemigrationsmigratesqlmigrateshowmigrations其中前三个命令在第二篇笔记中已经介绍过了。这里介绍一下showmigrations。这个功能主要是检查一个应用下的迁移文件是否已经改成数据库了。可以在Django系统根目录使用如下命令测试:python3manage.pyshowmigrationsblog可以看到如下输出:blog[X]0001_initial[X]0002_auto_20220118_0926[X]0003_auto_20220121_1016其中,前面的[X]]表示已经改成数据库了。如果我们任意修改博客的模型,然后执行makemigrations操作,再次执行showmigrations操作,可以看到如下输出:blog[X]0001_initial[X]0002_auto_20220118_0926[X]0003_auto_20220121_1016[]0004_alter_book_price可以看到最下面的记录[]里面没有X,说明这个迁移文件还没有被迁移。2.迁移文件介绍makemigrations生成的每一个迁移文件都存在于系统中。基本迁移文件如下所示:fromdjango.dbimportmigrations,modelsclassMigration(migrations.Migration):dependencies=[('blog','0001_initial')]operations=[migrations.DeleteModel('Tribble'),migrations.AddField('Author','rating',models.IntegerField(default=0)),]一个Migration类下,有两个Parameters,一个是dependencies,一个是operationsdependencies。作用是定位上次执行的迁移文件,因为每次迁移都是按顺序执行的,它的参数是一个列表。列表的元素是一个元组,其中包含两个参数,一个是应用程序的名称,一个是上次运行的迁移文件。它可以分配给多个应用程序,也就是说在两个应用程序的迁移文件之后执行操作的功能是它需要在迁移中执行。操作可以是字段的增、删、改,也可以是表的创建、删除。一个migration在执行migrate之前,我们可以手动修改,甚至可以完全自己定义。3.自定义迁移文件上面介绍的迁移文件的基本结构,有一些关于字段和模型的操作方法,这些操作可以通过makemigration自动生成。我们自定义的迁移文件应该和上面一致。自定义迁移文件中需要修改的部分是operations中的元素。假设我们有这样的需求,创建一个基本的映射表后,里面包含了系统运行所必需的数据,需要在创建表后立即写入,这时使用我们自定义的迁移文件。除了修改表字段或表外,还有两种写入数据的方式。一种是使用SQL语句插入,使用的迁移函数是RunSQL()。另一种是用Django的ORM语句写python。插入函数,函数是RunPython,假设创建Blog表的迁移文件是0001_create_blog.py现在需要插入两条数据,name和tagline分别是('name_1','tagline_1')和('name_2','tagline_2'分别)下面分别用RunSQL()和RunPython()来介绍。4.RunSQL()RunSQL()函数接受一个字符串或数组作为参数,参数的内容都是SQL语句,这也是该函数命名为RunSQL()的原因。字符串的形式就是一条完整的SQL语句。比如我们需要插入这两条数据,就是:migrations.RunSQL("INSERTINTOblog_blog(name,tagline)values('name_x_4','tagline_1'),('name_x_5','tagline_2');")如果以数组形式传入,则格式为:migrations.RunSQL(sql=[("INSERTINTOblog_blog(name,tagline)values(%s,%s),(%s,%s);",['name_x_6','tagline_1','name_x_7','tagline_2'])])在数组的传入形式中,我们把所有要插入的数据放到一个数组中,传给reverse_sqlRunSQL()除了sql参数,该函数还有一个reverse_sql参数,作为sql参数执行的sql语句执行不成功时的操作,一般用于防止数据污染。假设我们的sql是要插入数据的,但是由于某种原因,这条语句没有插入正确而报错,那么系统就会把reverse_sql中的语句作为可逆操作来执行。下面是官方的用法示例:migrations.RunSQL(sql=[("INSERTINTOmusician(name)VALUES(%s);",['Reinhardt'])],reverse_sql=[("DELETEFROMmusicianwherename=%s;",['Reinhardt'])],)5.RunPython()RunSQL()函数对SQL语句进行操作,RunPython()参数是一个Python函数,可以写入我们需要写入的所有数据到函数,然后在RunPython()中调用以下内容:definsert_blog_data(apps,schema_editor):Blog=apps.get_model("blog","Blog")db_alias=schema_editor.connection.aliasBlog.objects.using(db_alias).create(name="name_3",tagline="tagline_3")Blog.objects.using(db_alias).create(name="name_4",tagline="tagline_4")类迁移(migrations.Migration):dependencies=[("blog","0001_initial"),]operations=[migrations.RunPython(insert_blog_data)]其中insert_blog_data是需要执行的函数。在这个函数中,有两个默认参数,apps和schema_editorapps可以用来获取我们需要的模型,根据函数apps.get_model(),这个函数传入两个参数,一个是application,我们这里是blog,一个模型的名字,这里我们是Blog,schema_editor是可以用来获取数据库的别名。然后,插入数据的方式和普通机型的操作方法是一致的。RunPython()函数和RunSQL类似,也可以输入两个参数。第二个参数也用于操作失败的回退操作:migrations.RunPython(insert_blog_data,reverse_insert)以上就是迁移的全部内容。下一篇笔记将介绍如何使用Django使用原生SQL查询数据。