django數據庫表結構自動遷移

django south 使用教程(1)

一、下載與安裝

south安裝包下載地址:https://bitbucket.org/andrewgodwin/south/

south文檔:http://south.readthedocs.org/en/latest/

二、south簡介

Django 的第三方 app South 就是專門做數據庫表結構自動遷移工作,Jacob Kaplan-Moss 曾做過一次調查,South 名列最受歡迎的第三方 app。事實上,它現在已經儼然成爲 Django 事實上的數據庫表遷移標準,很多第三方 app 都會帶 South migrations 腳本。

三、回顧syncdb

syncdb是db synchronization的縮寫,意思是數據庫同步。

syncdb 命令是同步你的模型到數據庫的一個簡單方法。 它會根據 INSTALLED_APPS 裏設置的app來檢查數據庫, 如果表不存在,它就會創建它。 需要注意的是, syncdb 並不能將模型的修改或刪除同步到數據庫;如果你修改或刪除了一個模型,並想把它提交到數據庫,syncdb並不會做出任何處理。

如果你再次運行 python manage.py syncdb ,什麼也沒發生,因爲你沒有添加新的模型或者添加新的app。因此,運行python manage.py syncdb總是安全的,因爲它不會重複執行SQL語句。

知識總結:遷移( migrations?)

四、爲什麼用south

對於二、三兩點,可知syncdb的不足,如果更改了models,如添加一列等此時syncdb就沒有用武之地了,如果硬手工修改表結構不僅容易出錯,又不安全,並非權宜之計,而south卻能很好的解決該問題。

south特性:

(1)、自動遷移:south可自動檢測你的Models.py文件的改變,自動寫入migrations去匹配你所做的改變。

(2)、數據庫獨立性:完全與數據庫無關的,支持五個不同的數據庫後端。這樣就無需再關注於數據庫方向,而專注與django。

(3)、app藝術:south依賴app,south本身也是django的第三方app,再在使用的時候單獨作用於每個app下,進行遷移,同步。

(4)、VCS處理:south也能處理如果別人提交遷移到相同的應用程序作爲你和他們衝突。

你寫的遷移(migrations),它告訴south如何從一個版本升級到下一個,和通過串接在一起你可以移動這些遷移向前(或向後)通過歷史數據庫的模式。south也能創建新的model

五、快速指南

1、安裝完South之後,要在django項目中使用South,先要將South作爲一個App導入項目,所以設置INSTALL_APP添加south 第一次使用South。

2、manage.py syncdb 用來創建south_migrationhistory表。

3、manage.py convert_to_south youappname #在youappname目錄下面創建migrations目錄以及第一次遷移需要的0001_initial.py文件

4、如果改變了model裏的內容,./manage.py schemamigration youappname --auto #檢測對models的更改

manage.py migrate youappnam #將更改反應到數據庫(如果出現表已存在的錯誤,後面加 --fake)

如果第一次使用:
1、./manage.py schemamigration youappname --initial # youappname目錄下面創建一個migrations的子目錄(注意!!就算有多個app,也只要initial一個就可以)
2、./manage.py syncdb #初始化數據表等

#以後每次對models更改後,可以運行以下兩條命令同步到數據庫
3、./manage.py schemamigration youappname --auto #檢測對models的更改
4、./manage.py migrate youappnam #將更改反應到數據庫(如果出現表已存在的錯誤,後面加 --fake)

推薦教程:

http://codinn.com/people/brant/notes/110932/

http://a280606790.iteye.com/blog/1107657

六、深入基礎教程(首度使用)

1、新建models

新建southtut app,然後定義models如下:

class Knight(models.Model):
    name = models.CharField(max_length=100)
    of_the_round_table = models.BooleanField()

然後使用 syncdb 爲它創建一個遷移。

2、第一個遷移

south創建遷移有以下兩種方式:自動和手動,對於新手來說推薦兩種自動方式:--auto和--initial.

我們使用manage.py schemamigration app_name時候:(schema  migration:模式 遷移,簡化爲schemamigration)

--auto:作用於舊的(已經存在)的遷移(migration),對一些改變做出遷移工作,如增加字段等。

--initial:針對新的(尚未存在)的遷移,將創建表和索引對應到app 的models下。這是當你定義好model後的初步使用,如同syncdb一樣。

接下來開始創建第一個遷移

複製代碼
E:\project\demo>manage.py schemamigration southtut --initial
Creating migrations directory at 'E:\project\demo\southtut\migrations'...#創建遷移目錄migrations
Creating __init__.py in 'E:\project\demo\southtut\migrations'...#創建__init__.py
 + Added model southtut.Knight                                  #增加model
Created 0001_initial.py. You can now apply this migration with: ./manage.py migrate southtut#創建版本控制
複製代碼

完了之後,在項目目錄結構中可見以下改變:

當然也創建了該model:southtut.Knight

那麼接下來就應用新的遷移,注意如果已經存在該model則使用 --fake

E:\project\demo>manage.py migrate southtut --fake  #啓動
Running migrations for southtut:                   #啓動該app下的migrations
 - Migrating forwards to 0001_initial.             #正向前遷移
 > southtut:0001_initial
   (faked)

3、應用改變

這裏添加一個字段,要把給字段給同步上去。

class Knight(models.Model):
    name = models.CharField(max_length=100)
    of_the_round_table = models.BooleanField()
    dances_whenever_able = models.BooleanField()  #新增

那麼接下來就是同步了,此時分兩個步驟:

(1)、創建遷移:manage.py schemamigration southtut --auto

E:\project\demo>manage.py schemamigration southtut --auto  #此時用 --auto
 + Added field dances_whenever_able on southtut.Knight     #做出的改變
Created 0002_auto__add_field_knight_dances_whenever_able.py. #創建遷移版本
You can now apply this migration with: ./manage.py migrate southtut

(2)、應用:manage.py migrate southtut

複製代碼
E:\project\demo>manage.py migrate southtut
Running migrations for southtut:
 - Migrating forwards to 0002_auto__add_field_knight_dances_whenever_able.
 > southtut:0002_auto__add_field_knight_dances_whenever_able
 - Loading initial data for southtut.
No fixtures found.
複製代碼

完成之後,則發現已經添加了該字段

七、深入基礎教程(遷移使用)

1、基本流程

對於已經之前已經存在的model,如果我們使用south則不能使用上面的步驟。比如說,我有一個名爲other的app下model早已建立並且同步至數據庫,那麼我想要用south,那麼就要作如下處理了。

複製代碼
#已存在的model且裏面存有數據
class Contact(models.Model):
    name = models.CharField(max_length=30)
    email = models.EmailField()
    comment = models.CharField(max_length=100)
    def __unicode__(self):
        return self.name
    class Meta:
        db_table='contact'
複製代碼

ok,我要用這個,且在model裏動了手腳。

#Contact
...
age = models.IntegerField()  #添加

那麼使用south如下:

(1)、創建遷移:(--auto

manage.py schemamigration other --auto
.....#省略

(2)、應用:

manage.py migrate other
#...省略

流程給出了,但是爲什麼省略輸出的部分呢,因爲這裏涉及到一個知識點,就是Defaults:

2、defaults

對於上面southtut app model存在BooleanField,則該字段默認的default=False,然而對於其他字段,可能沒有定義默認字段,如果列爲空,既null=True,那麼新生成的列就沒有威脅了,否則就必須給出默認值,因爲對於已經存在數據的model,新的字段不可能沒有值。一些數據庫後端將讓你添加列,如果表是空的,而有些會拒絕徹底。

針對這種情況,south將會給出選擇並執行

#Contact
...
website = models.CharField(max_length=100,null=False)  #新增
..
複製代碼
E:\project\demo>manage.py schemamigration other --auto
 ? The field 'Contact.website' does not have a default specified, yet is NOT NULL.   #問題
 ? Since you are adding this field, you MUST specify a default value to use for existing rows. Would you like to:
 ?  1. Quit now, and add a default to the field in models.py    #退出,在models手動添加默認值
 ?  2. Specify a one-off value to use for existing columns now  #指定默認值
 ? Please select a choice:
複製代碼
複製代碼
.....
 ? Please select a choice: 2             #我的選擇
 ? Please enter Python code for your one-off default value.
 ? The datetime module is available, so you can do e.g. datetime.date.today()
 >>> 'http://www.google.com'             #指定的默認值
 + Added field website on other.Contact  #添加成功
Created 0006_auto__add_field_contact_website.py. You can now apply this migration with: ./manage.py migrate other
複製代碼
複製代碼
#應用
E:\project\demo>manage.py migrate other
Running migrations for other:
 - Migrating forwards to 0006_auto__add_field_contact_website.
 > other:0006_auto__add_field_contact_website
 - Loading initial data for other.No fixtures found.
複製代碼

3、Uniques

還有一點重要的是unique屬性

複製代碼
class Contact(models.Model):
    name = models.CharField(max_length=30,unique=True)#更改了
    email = models.EmailField()
    comment = models.CharField(max_length=100)
    website = models.CharField(max_length=100,null=False)  #新增
    def __unicode__(self):
        return self.name
    class Meta:
        db_table='contact'
複製代碼
複製代碼
E:\project\demo>manage.py schemamigration other --auto
 + Added unique constraint for ['name'] on other.Contact
Created 0007_auto__add_unique_contact_name.py. You can now apply this migration
with: ./manage.py migrate other

#還可以這樣:
E:\project\demo>manage.py schemamigration --auto other
複製代碼

然後再manage.py migrate southtut 就ok了。

4、ManyToMany fields

south能夠檢測多對多字段,South will create the table the ManyToMany represents, and when you remove the field, the table will be deleted.

 

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