Django遷移

Django遷移

學習目標:python

  • 如何在不編寫任何SQL語句的狀況下建立數據庫表
  • 更改model如何自動修改數據庫
  • 如何還原對數據庫所作的更改

遷移能解決的問題

若是你不瞭解Django或者WEB開發,確定是不熟悉數據庫遷移的概念的。git

在學習它以前,首先咱們須要明確它是幹什麼的,Django使用它旨在與關係型數據庫結合使用,將數據存儲在PostgreSQL,Mysql或者SQLite等關係型數據庫管理系統中.github

在關係數據庫中,數據以表格形式組織。數據庫表具備必定數量的列,但它能夠包含任意數量的行。每列都有一個特定的數據類型,如某個特定最大長度的字符串或正整數。全部表及其列及其各自數據類型的描述稱爲數據庫模式。sql

Django支持的全部數據庫系統都使用語言SQL來建立,讀取,更新和刪除關係數據庫中的數據。SQL還用於建立,更改和刪除數據庫表自己。shell

直接使用SQL可能很是麻煩,所以爲了讓咱們的開發工做更加輕鬆,Django附帶了一個對象關係映射器,簡稱ORM。ORM將關係數據庫映射到面向對象編程的世界。能夠在Python中編寫Django模型,而不是在SQL中定義數據庫表。模型定義數據庫字段,這些字段對應於其數據庫表中的列。數據庫

如下是Django模型類如何映射到數據庫表的示例:django

可是隻是在Python文件中定義一個模型類並不會使數據庫表格無處不在。建立數據庫表來存儲Django模型是數據庫遷移的工做。此外,不管什麼時候對模型進行更改(如添加字段),都必須更改數據庫。遷移也處理這個問題。編程

如下是Django遷移讓咱們的開發工做更加輕鬆的幾種方式:session

一、不使用SQL對數據庫進行修改

在Django中,若是沒有遷移,就必須在使用的時候連接到數據庫而且輸入一堆SQL命令,或者使用一些圖形工具在每次要更改模型定義時修改數據庫模式。架構

在Django中,遷移主要是用Python代碼完成的,所以除非你有很是高級的需求用法,不然你不須要操做任何SQL。

二、避免重複

若是建立模型後,編寫sql語句建立數據庫表,則會形成重複現象。

可是從模型中生成遷移,就能確保不會重複

三、確保模型定義和數據模式同步

一般,咱們會有多個數據庫實例,例如,團隊中每一個開發人員的一個數據庫,用於測試的數據庫和包含實時數據的數據庫。

若是沒有遷移,則必須對每一個數據庫執行任何模式更改,而且必須跟蹤已對哪一個數據庫進行了哪些更改。

使用Django Migrations,就能夠輕鬆地使多個數據庫與模型保持同步。

四、跟蹤版本控制(git)中的數據庫模式更改

像Git這樣的版本控制系統很是適合代碼,但對數據庫模式來講並非那麼多。

因爲遷移在Django中是普通的Python,所以您能夠將它們放在版本控制系統中,就像任何其餘代碼同樣。

建立遷移

在遷移以前首先得建立一個Django項目,具體怎麼建立就不作過多贅述啦。直接開始吧

在作遷移以前,咱們首先要建立模型。在app01/models.py中添加此類

class User(models.Model):
    name = models.CharField(max_length=32)
    password = models.CharField(max_length=64)

一個最簡單的用戶模型類。

模型建立完成以後的第一件事就是爲他建立遷移。

> python manage.py makemigrations
注意:
# 有的同窗執行了以上命令後會發現不行,報錯了
"""
File "manage.py", line 16
    ) from exc
         ^
SyntaxError: invalid syntax
"""
這就很難受了,爲何呢,由於隨着時間的增加,Django的版本已經更新到2.3之後了,而在Django1.7之後,執行以上代碼都會報這個錯誤。咱們須要將python替換成python3

> python3 manage.py makemigrations

"""
Migrations for 'hello_world':
  hello_world/migrations/0001_initial.py
    - Create model User
"""
這就成功了!!!

執行成功後,在migrations目錄如今包含一個新文件:0001_initial.py

"""
當咱們運行完 makemigrations 命令,若是你沒有配置數據庫,它還會自動建立db.sqlite3數據庫.這個是Django默認的配置,同時也是SQLite獨有的配置。若是是其餘數據庫的話,例如:Mysql、PostgreSQL等,就必須在運行以前本身建立數據庫了
"""

遷移成功後,咱們接着來查看你的數據庫,會發現它雖然被建立出來了,可是他依然是空的。

> python3 manage.py dbshell

SQLite version 3.24.0 2018-06-04 14:10:15
Enter ".help" for usage hints.
sqlite> .tables
sqlite>

應用遷移

雖然如今咱們已經建立了遷移工做,可是要想要實際在數據庫中進行任何修改,就必須執行migrate命令:

> python3 manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, hello_world, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying hello_world.0001_initial... OK
  Applying sessions.0001_initial... OK

執行完這條命令,會發現有不少輸出,根據輸出來看,咱們的遷移已經成功應用,那麼這些遷移中還有一些咱們不知道的東西,它們來自於哪裏呢?

還記得配置文件中的INSTALLED_APPS嗎?其中列出的其餘一些應用程序也帶有遷移功能,migrate管理命令默認狀況下會爲全部已安裝的應用程序應用遷移。

再來看一下數據庫:

SQLite version 3.24.0 2018-06-04 14:10:15
Enter ".help" for usage hints.
sqlite> .tables
auth_group                  django_admin_log          
auth_group_permissions      django_content_type       
auth_permission             django_migrations         
auth_user                   django_session            
auth_user_groups            hello_world_user          
auth_user_user_permissions
sqlite>

如今咱們的數據庫已經出現了多個表,咱們能夠從他們的名字上來了解他們的做用。

# 能夠經過.schema命令查看已經生成的表
sqlite> .schema --indent hello_world_user
CREATE TABLE IF NOT EXISTS "hello_world_user"(
  "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
  "name" varchar(32) NOT NULL,
  "password" varchar(64) NOT NULL
);

"""
.schema命令打印出CREATE將執行以建立表的語句。該參數--indent將sql語句格式化。即便不熟悉SQL語法,也能夠看到hello_world_user表的模式反映了user模型的字段。
"""

若是你再次進行遷移的話,會發現不會將全部的模型表從新執行一遍,由於Django會記住已經應用了那些遷移,不會對已經遷移過的,在從新運行。

模型修改

你的model文件必定不是一成不變的,隨着你項目的完善,功能的添加,你的模型確定會發生變化,能夠添加、刪除字段或者更改類型還有選項。

在更改模型類的時候,確定還須要更改用於存儲這些模型的數據庫表。若是模型定義與當前數據模式不匹配,極可能就會報錯:django.db.utils.OperationalError

具體更改方法:

依次執行:
> python3 manage.py makemigrations
> python3 manage.py migrate

列出遷移

若是想要知道項目中存在那些遷移,能夠直接經過如下命令查看

python3 manage.py showmigrations

取消應用遷移

建立以及應用遷移都已經搞定了,知道如如何經過它們去更改數據庫模式,可是有些時候咱們可能須要執行一些撤銷操做以切換回早期的數據庫模式,好比:

  • 測試公司項目的中寫的遷移
  • 遷移以後出現bug
  • 同時處理不一樣數據庫修改的多個功能
  • 想要還原在數據庫中具老架構的備份

因此這個時候就須要取消遷移來幫助咱們了。

> python3 manage.py migrate hello_world 0001_initial

執行它就能夠將遷移取消應用,也意味着對數據庫的更改也被取消了

取消應用遷移不會刪除其遷移文件。下次運行該migrate命令時,將再次應用遷移。

警告:
"""
不要將未應用的遷移與您最經常使用的文本編輯器中的撤消操做混淆。
並不是全部數據庫操做均可以徹底還原。若是從模型中刪除字段,建立遷移並應用它,Django將從數據庫中刪除相應的列。
取消應用遷移將從新建立列,但它不會帶回存儲在該列中的數據!
"""

總結

Django遷移的基本步驟:

  • 建立或更新模型類
  • 執行 python3 manage.py makemigrations <app name(可不寫)>
  • 執行python3 manage.py migrate遷移全部內容或python3 manage.py migrate <app name>遷移單個app
  • 根據需求重複操做

這個工做流程在大多數狀況下均可以搞定,但若是事情沒有按預期進行,還能夠列出或者取消應用遷移幫助咱們操做。

相關文章
相關標籤/搜索