Django笔记二十之手动编写migration文件

科技资讯 投稿 13500 0 评论

Django笔记二十之手动编写migration文件

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

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

    基础命令
  1. migration文件介绍
  2. 自定义migration文件
  3. RunSQL(
  4. RunPython(

1、基础命令

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

    makemigrations
  • migrate
  • sqlmigrate
  • 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文件介绍

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

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

一个 migration 在执行 migrate 前,我们可以手动对其修改,甚至可以完全自己来定义

3、自定义migration文件

我们自定义的 migration 文件,与上面的保持一致即可,自定义的 migration 文件需要修改的地方是 operations 里的元素。

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

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

现在需要对其插入两条数据,name 和 tagline 分别是 ('name_1', 'tagline_1' 和 ('name_2', 'tagline_2'

4、RunSQL(

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

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 语句没有执行成功的情况下的一种操作,一般是用于防止数据污染。

以下是官方的一个使用示例:

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

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

而 schema_editor 则是可以用于获取数据库的 alias

RunPython( 函数和 RunSQL 一样,也可以输入两个参数,第二个参数作用也是用于操作失败的回退操作:

migrations.RunPython(insert_blog_data, reverse_insert

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

编程笔记 » Django笔记二十之手动编写migration文件

赞同 (70) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽