Django Migrate 框架原理分析

Django 框架简介

一句话介绍:Django 是用来写网站。
Django的主要目的是简便、快速的开发数据库驱动的网站。它强调代码复用,多个组件可以很方便的以“插件”形式服务于整个框架,Django有许多功能强大的第三方插件,你甚至可以很方便的开发出自己的工具包。这使得Django具有很强的可扩展性。它还强调快速开发和DRY(Do Not Repeat Yourself)原则。

 

官方文档描述
Django 最初被设计用于具有快速开发需求的新闻类站点,目的是要实现简单快捷的网站开发。

 

主要功能特性:

 

  • 对象关系映射 (ORM,object-relational mapping):以Python类形式定义你的数据模型,ORM将模型与关系数据库连接起来,你将得到一个非常容易使用的数据库API,同时你也可以在Django中使用原始的SQL语句。

  • URL 分派:使用正则表达式匹配URL,你可以设计任意的URL,没有框架的特定限定。像你喜欢的一样灵活。

  • 模版系统:使用Django强大而可扩展的模板语言,可以分隔设计、内容和Python代码。并且具有可继承性。

  • 表单处理:你可以方便的生成各种表单模型,实现表单的有效性检验。可以方便的从你定义的模型实例生成相应的表单。

  • Cache系统:可以挂在内存缓冲或其它的框架实现超级缓冲 -- 实现你所需要的粒度。

  • 会话(session),用户登录与权限检查,快速开发用户会话功能。

  • 国际化:内置国际化系统,方便开发出多种语言的网站。

  • 自动化的管理界面:不需要你花大量的工作来创建人员管理和更新内容。Django自带一个ADMIN site,类似于内容管理系统

MVC(MVT)

 

image

 

M 代表模型(Model),即数据存取层。 该层处理与数据相关的所有事务: 如何存取、如何验证有效性、包含哪些行为以及数据之间的关系等。
T 代表模板(Template),即表现层。 该层处理与表现相关的决定: 如何在页面或其他类型文档中进行显示。
V 代表视图(View),即业务逻辑层。 该层包含存取模型及调取恰当模板的相关逻辑。 你可以把它看作模型与模板之间的桥梁。

 

ORM 框架简介

 
ORM 框架就是一种 对象关系映射(Object Relational Mapping,简称ORM), 是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。

 

    字母O起源于"对象"(Object),而R则来自于"关系"(Relational)。几乎所有的网站应用程序里面,都存在对象和关系数据库。在业务逻辑层和用户界面层中,我们是面向对象的。当对象信息发生变化的时候,我们需要把对象的信息保存在关系数据库中。

 

       当你开发一个应用程序的时候(不使用O/R Mapping),你可能会写不少数据访问层的代码,用来从数据库保存,删除,读取对象信息,等等。你在DAL中写了很多的方法来读取对象数据,改变状态对象等等任务。而这些代码写起来总是重复的。
 
       ORM解决的主要问题是对象关系的映射。域模型和关系模型分别是建立在概念模型的基础上的。域模型是面向对象的,而关系模型是面向关系的。一般情况下,一个持久化类和一个表对应,类的每个实例对应表中的一条记录,类的每个属性对应表的每个字段。

 

ORM优点缺点:

 

使用 ORM 最大的优点就是快速开发,让我们将更多的精力放在业务上而不是数据库上,下面是 ORM 的几个优点

  • 隐藏了数据访问细节,使通用数据库交互变得简单易行。同时 ORM 避免了不规范、冗余、风格不统一的 SQL 语句,可以避免很多人为的 bug,方便编码风格的统一和后期维护。

  • 将数据库表和对象模型关联,我们只需针对相关的对象模型进行编码,无须考虑对象模型和数据库表之间的转化,大大提高了程序的开发效率。

  • 方便数据库的迁移。当需要迁移到新的数据库时,不需要修改对象模型,只需要修改数据库的配置。

 

ORM 的最令人诟病的地方就是性能问题,不过现在已经提高了很多,下面是 ORM 的几个缺点

  • 性能问题

    • 自动化进行数据库关系的映射需要消耗系统资源

    • 程序员编码

    • 在处理多表联查、where 条件复杂的查询时,ORM 可能会生成的效率低下的 SQL

    • 通过 Lazy load 和 Cache 很大程度上改善了性能问题

  • SQL 调优,SQL 语句是由 ORM 框架自动生成,虽然减少了 SQL 语句错误的发生,但是也给 SQL 调优带来了困难。

  • 越是功能强大的 ORM 越消耗内存,因为一个 ORM Object 会带有很多成员变量和成员函数。

  • 对象和关系之间并不是完美映射

 

一般来说 ORM 足以满足我们的需求,如果对性能要求特别高或者查询十分复杂,可以考虑使用原生 SQL 和 ORM 共用的方式

 

常用的框架

python
Sqlalchmy(3.2★), Peewee(5.9★), Django(38.1★),
Java
Hibernate(3.5★),MyBatis(5.1★)

Django ORM 框架使用

数据库表结构变更

id

name

email

phone

1

陈独秀

chenduxiu@souche.com

13712345678

2

李大钊

lidazhao@souche.com

15612345678

 

1. 定义model

#!/usr/bin/env python
from django.db import models
from django.db.models import CharField


class User(models.Model):
    name = CharField(max_length=32)
    email = CharField(max_length=32)
    phone = CharField(max_length=32)

    class Meta:
        db_table = 'user'
        verbose_name = 'user table'
        verbose_name_plural = 'user table'

2. 生成迁移文件

$ python manage.py makemigrations
Migrations for 'blog':
  blog/migrations/0001_initial.py
    - Create model User

生成的迁移文件如下:

# Generated by Django 2.1.3 on 2018-12-07 03:34

from django.db import migrations, models


class Migration(migrations.Migration):

    initial = True

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='User',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(max_length=32)),
                ('phone', models.CharField(max_length=32)),
                ('email', models.CharField(max_length=32)),
            ],
            options={
                'verbose_name': 'user table',
                'verbose_name_plural': 'user table',
                'db_table': 'user',
            },
        ),
    ]

 

3. 执行迁移命令

python manage.py migrate blog

 

  • 记录数据库版本信息到表 django_migrations 中。

  • 生成表格变更 SQL 语句,并执行。

$ python manage.py migrate blog
Operations to perform:
  Apply all migrations: blog
Running migrations:
  Applying blog.0001_initial... OK

 

数据查询

Django ORM 学习笔记

 

user1 = User.objects.all().first()
user1.name  # 陈独秀
user1.email  # chenduxiu@souche.com

user2 = User.object.all()[1]
user2.name  # 李大钊
user2.email  # lidazhao@souche.com

 

Django ORM 框架原理分析

数据库迁移(表结构变更)

 

image

#!/usr/bin/env python
from django.db import models
from django.db.models import CharField


class User(models.Model):
    name = CharField(max_length=32)
    email = CharField(max_length=32)
    phone = CharField(max_length=32)

    class Meta:
        db_table = 'user'
        verbose_name = 'user table'
        verbose_name_plural = 'user table'

 

BEGIN;
--
-- Create model User
--
CREATE TABLE `user` (
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, 
`name` varchar(32) NOT NULL, `phone` varchar(32) NOT NULL,
`email` varchar(32) NOT NULL
);
COMMIT;

 

1. 生成数据库版本文件

python manage.py makemigrations blog

  1. 配置文件检查,配置信息获取(数据库,InstallApp), 合并迁移检查等

  1. 检查 Model 变更

  1. 根据变更结果,写入迁移文件

 

MigrationLoader

  1. 加载数据库信息,加载所有 app 的migrations 文件生成迁移依赖图  MigrationGraph 对象

 

image

 

MigrationAutodetector
_detect_changes 方法
检查 model, index, field 变更操作(重命名,删除,新增,修改)。

 

createdmodel 检查

 

image

 

image

 

检查完后生成变更 dict 对象。

 

image

 

MigrationWriter
根据检查变更完的 dict 对象。生成迁移文件代码并保存到对应目录。

 

python manage.py sqlmigrate blog 0001
python manage.py migrate blog 0001

 

MigrationExecutor

 

plan对象

 

image

 

image

 

Migration 类中的 apply 方法

 

image

 

BaseDatabaseSchemaEditor  类中 create_model 方法

  1. 遍历 model fields , 拿到feilds 的各个属性,拼接成创建表格的 SQL 语句,

  1. 向 django_migrations 记录迁移记录

  1. 执行生成的sql语句,进行数据库变更

 

image

 

image

 

数据库查询

 

image

 

ORM 查询时就是 把 api 变成 SQL 并执行的过程。

query_set = User.objects.all().first()



SELECT `user`.`id`, `user`.`name`, `user`.`phone`, `user`.`email` FROM `user` limit 1

SELECT * FROM `user` limit 1

 

SQLComplier 类

 

image

 

image

 

参考链接
sqlmigrate 命令 http://www.sohu.com/a/255896389_505857

 

Django orm 查询流程 [https://www.jianshu.com/p/ac87788b55f3](https://www.jianshu.com/p/ac87788b55f3)

 

migrate,makemigrations,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值