首页 > 其他分享 >Django笔记二十之手动编写migration文件

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

时间:2023-04-09 20:01:11浏览次数:56  
标签:文件 RunSQL name tagline 笔记 Django blog migration

本文首发于公众号:Hunter后端
原文链接: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 来查询数据。

如果想获取更多后端相关文章,可扫码关注阅读:
image

标签:文件,RunSQL,name,tagline,笔记,Django,blog,migration
From: https://www.cnblogs.com/hunterxiong/p/17300914.html

相关文章

  • 物理学习笔记
    圆锥曲线&万有引力能量式:\(E=\frac{1}{2}mv^2-G\frac{Mm}{r}\)椭圆数学相关\(e∈(0,1)\)\(S=πab\)第一定义:到定点的距离和为定值第二定义:\(e=\frac{动点到定点}{动点到定直线}\),其中定点为焦点,定直线为准线\(x=±\frac{a^2}{c}\)。参数方程:\(\begin{cases}x=acos......
  • #yyds干货盘点#Linux中root与sudo的用法与区别(学习笔记)
    Linux下面有两个概念可能大家接触的比较多,一个是sudo命令,还有一个是root账户。Sudo 命令可以以最高权限执行命令,而root账户下所有命令都有最高权限,也就是相当于所有命令都默认加了sudo。那么 sudo和root的区别到底是什么呢,为什么我们建议使用sudo而不是直接使用roo......
  • DX4600快速部署私有云笔记,思源笔记
    DX4600快速部署私有云笔记,思源笔记一、安装思源笔记首先我们打开Docker​管理器,进入镜像管理​。然后在镜像仓库中搜索b3log/siyuan​,选择latest​版本并下载。​​​​下载完成后,我们在本地镜像中找到刚刚下载的镜像,点击创建容器​。勾选创建后启动容器​,点击下一步。......
  • #yyds干货盘点#学习笔记3,Linux 安全强化 SSH 远程连接的方法
    7.使用SSH密钥连接连接到服务器的最安全方法之一是使用SSH密钥。使用SSH密钥时,无需密码即可访问服务器。另外,你可以通过更改sshd_config文件中与密码相关的参数来完全关闭对服务器的密码访问。创建SSH密钥时,有两个密钥:Public和Private。公钥将上传到你要连接的服务器,......
  • 人月神话阅读笔记04
    四月份的阅读笔记它来啦!1、为什么巴比伦塔会失败?巴比伦塔项目是继诺亚方舟之后的又一大工程项目,同时也是一个彻头彻尾的失败的项目,那么,这么大的工程为什么是一个彻底的失败呢?是它没有足够的人手?没有先进的技术?没有没有质量好的材料?不!都不是,他就是单纯地缺乏组织上的交流而已。......
  • 【动手学深度学习】第三章笔记:线性回归、SoftMax 回归、交叉熵损失
    这章感觉没什么需要特别记住的东西,感觉忘了回来翻一翻代码就好。3.1线性回归3.1.1线性回归的基本元素1.线性模型用符号标识的矩阵\(\boldsymbol{X}\in\mathbb{R}^{n\timesd}\)可以很方便地引用整个数据集中的\(n\)个样本。其中\(\boldsymbol{X}\)地每一行是一个样......
  • Markdown的学习笔记
    Markdown学习笔记1、Markdown的字体字体粗体斜体斜体加粗删除线2、Markdown的引用引用选择xxx走向人生巅峰3、Markdown的分割线分割线4、Markdown的图片插入图片插入图片 4、Markdown的超链接超链接点击跳转到tly的博客5、Markdown的列表列表列表1......
  • Khan公开课 - 统计学学习笔记:(二)总本、样本、集中趋势、离中趋势
    三、统计学&集中趋势统计学statistics是对数据的descriptive,而不是将所有数据呈现,根据统计,可以进行inferential(推理),对未来的判断。集中趋势CentralTendency,求中间值就是average,通常指的是mean(算术平均),但是广义上也包括median、和mode。计算的方式不同,不能说哪种方法好,看具体情况......
  • [笔记]VisionMobile:应用商店货币化的黄金路
    VisionMobile的Theyellowbrickroadofappstoremonetisation,分析和对比三个应用商店:Apple,Google已经Amazon,并认为Amazon的应用商店比Google的好。以下是要点笔记。这三个商店应用货币化数据比较:不同来源的数据有较大的差异。根据Flurry对应用内购买数据,Apple的最高,亚马逊和G......
  • Android学习笔记(五十):声明、请求和检查许可
    基于安全需求,应用对Android系统提供的contentprovider或者service的访问需要在安装时进行许可,这就是AndroidManifest.xml文件中的permission中声称,之前已经很多例子。同样如果其他应用要访问我们的数据,我们也可以要求这些应用必须获得用户授权方可访问我们的数据。申请授权:请求per......