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

陳獨秀

[email protected]

13712345678

2

李大釗

[email protected]

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  # [email protected]

user2 = User.object.all()[1]
user2.name  # 李大釗
user2.email  # [email protected]

 

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,

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章