乐趣区

关于python:Django笔记二十之手动编写migration文件

后面介绍过,migration 文件次要记录的是 Django 零碎 model 的变动,而后通过 migrate 命令将变动适配到数据库中。

比方在某个 application 下新增了某张表,或者对某张表更改了字段,能够生成 migration 文件,而后通过 migrate 更改到数据库。

除了零碎可能主动生成的,咱们还能够手动创立 migration 文件来操作数据库,这个用处次要是用于比方,创立表后,须要写入一些初始化的数据的状况。

  1. 根底命令
  2. migration 文件介绍
  3. 自定义 migration 文件
  4. RunSQL()
  5. RunPython()

1、根底命令

对于 migration 的命令有如下几条:

  • makemigrations
  • migrate
  • sqlmigrate
  • showmigrations

其中 后面三条命令在第二篇笔记中曾经介绍过应用办法,这里介绍一下 showmigrations。

这个作用次要是查看某个 application 下的 migration 文件是否曾经被更改到数据库中,能够在 Django 零碎的根目录用上面的命令测试:

python3 manage.py showmigrations blog

能够看到上面的输入:

blog
 [X] 0001_initial
 [X] 0002_auto_20220118_0926
 [X] 0003_auto_20220121_1016

其中,后面的 [X] 示意曾经被更改到数据库中,如果咱们再对 blog 的 model 进行任意批改,而后执行 makemigrations 的操作,再次执行 showmigrations 的操作,能够看到上面的输入:

blog
 [X] 0001_initial
 [X] 0002_auto_20220118_0926
 [X] 0003_auto_20220121_1016
 [] 0004_alter_book_price

能够看到最上面的一条记录 [] 中是没有 X 的,示意这条 migration 文件没有被执行 migrate。

2、migration 文件介绍

每一次通过 makemigrations 生成的 migration 文件都存在零碎中,一个最根底的 migration 文件像上面这样:

from django.db import migrations, models


class Migration(migrations.Migration):


    dependencies = [('blog', '0001_initial')]


    operations = [migrations.DeleteModel('Tribble'),
        migrations.AddField('Author', 'rating', models.IntegerField(default=0)),
    ]

一个 Migration 的类下,有两个参数,一个是 dependencies,一个是 operations

dependencies 作用是定位上一个执行的 migration 文件的中央,因为每一次 migrate 的执行都是依照程序的

且他的参数是一个列表,列表的元素是一个元组,外面有两个参数,一个是 application 的名称,一个是上一次运行的 migration 文件,他是能够指定到多个 application 的,意义为在某两个 application 的 migration 文件之后再执行

operations 的作用是 migration 里须要执行的操作,能够是字段的减少、删除、批改、也能够是表的创立和删除

一个 migration 在执行 migrate 前,咱们能够手动对其批改,甚至能够齐全本人来定义

3、自定义 migration 文件

后面介绍了 migration 文件的根本构造,其中有一些对于字段和 model 的操作方法,这些操作都能够通过 makemigration 的形式主动生成。

咱们自定义的 migration 文件,与下面的保持一致即可,自定义的 migration 文件须要批改的中央是 operations 里的元素。

假如咱们有这样一个需要,创立一张根底映射表后,外面是零碎运行所必须的数据,须要在创立表后立刻写入,那么就用到了咱们这个自定义的 migration 文件。

除了对表字段或者表的批改,还有两种办法实现数据的写入,

一种是应用 SQL 语句插入,用到的 migration 的函数是 RunSQL()

一种是应用 Django 的 ORM 语句,写 python 的函数来插入,函数是 RunPython

假如创立 Blog 表的 migration file 是 0001_create_blog.py

当初须要对其插入两条数据,name 和 tagline 别离是 (‘name_1’, ‘tagline_1’) 和 (‘name_2’, ‘tagline_2’)

上面用 RunSQL() 和 RunPython() 两种形式来别离介绍。

4、RunSQL()

RunSQL() 函数承受一个字符串,或者一个数组作为参数,参数的内容都是 SQL 语句,这也是为什么函数名为 RunSQL()。

字符串的模式为残缺的 SQL 语句,比方咱们须要插入这两条数据,则是:

migrations.RunSQL("INSERT INTO blog_blog (name, tagline) values('name_x_4','tagline_1'), ('name_x_5','tagline_2');"
)

如果是作为数组传入,模式则是:

migrations.RunSQL(
    sql=[
        ("INSERT INTO blog_blog (name, tagline) values(%s, %s), (%s, %s);",
            ['name_x_6', 'tagline_1', 'name_x_7', 'tagline_2']
        )
    ]
)

在数组的传入模式中,咱们将须要插入的数据都放到一个数组中传入

reverse_sql
RunSQL() 函数除了 sql 参数,还有一个 reverse_sql 参数,用处是 sql 参数执行的 SQL 语句没有执行胜利的状况下的一种操作,个别是用于避免数据净化。

假如说咱们的 sql 为插入数据,然而因为某种原因,这条语句没有正确插入,报错了,那么零碎就会执行 reverse_sql 中的语句,作为一个可逆的操作。

以下是官网的一个应用示例:

migrations.RunSQL(sql=[("INSERT INTO musician (name) VALUES (%s);", ['Reinhardt'])],
    reverse_sql=[("DELETE FROM musician where name=%s;", ['Reinhardt'])],
)

5、RunPython()

RunSQL() 函数操作的是 SQL 语句,RunPython() 参数则是 Python 函数,能够将咱们须要写入的数据都写到函数的步骤里,而后在 RunPython() 中调用

以下是应用示例:

def insert_blog_data(apps, schema_editor):
    Blog = apps.get_model("blog", "Blog")
    db_alias = schema_editor.connection.alias

    Blog.objects.using(db_alias).create(name="name_3", tagline="tagline_3")
    Blog.objects.using(db_alias).create(name="name_4", tagline="tagline_4")



class Migration(migrations.Migration):
    dependencies = [("blog", "0001_initial"),
    ]


    operations = [migrations.RunPython(insert_blog_data)
    ]

其中,insert_blog_data 是须要执行的函数,在这个函数里,有两个默认参数,apps 和 schema_editor

apps 能够用来获取咱们须要的 model,依据函数 apps.get_model(),

这个函数传入两个参数,一个是 application,咱们这里是 blog,

一个 model 的名称,咱们这里是 Blog

而 schema_editor 则是能够用于获取数据库的 alias

而后,数据的插入的形式就和一般的 model 的操作方法统一了。

RunPython() 函数和 RunSQL 一样,也能够输出两个参数,第二个参数作用也是用于操作失败的回退操作:

migrations.RunPython(insert_blog_data, reverse_insert)

以上就是介绍 migration 的全部内容了,下一篇笔记将介绍如何在 Django 中应用原生的 SQL 来查问数据。

本文首发于自己微信公众号:Django 笔记。

原文链接:Django 笔记二十之手动编写 migration 文件

如果想获取更多相干文章,可扫码关注浏览:

退出移动版