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.