Cody Blog

使用 south 來做 Django database migration

一般在 Django 底下更動 model 的時侯,必須使用 syncdb 這個指令,把修改的 model 同步到 database 之中,但是有個限制,就是只有新的 model 才會被更新,已經存在的 model 就不會更動,此時就需要south的幫忙。在 django 1.7 之後,這個 library 正式被整進到 django 之中。不過目前我手頭上的專案還是以 1.6 為主,所以還是要筆記一下。

初始化 south

安裝完 south 之後,第一次先執行 syncdb 把 south 相關的south_migrationhistory 新增到資料庫中。

$ ./manage.py syncdb

開始 migration

首先要介紹的是 schemamigration <APP_NAME> --initial,這個指令會在 app 資料夾下面產生一個 migrations 資料夾。如果是第一次執行的話,裡面的檔名會是 0001_initial.py 開頭,裡面會記錄如何從無到有,把資料表建立起來。

def forwards(self, orm):
    # Adding model 'UserModel'
    db.create_table(u'dusers_dmodel', (
        (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),

此時可以執行 syncdb 做一下確認

$ python manage.py syncdb …

Django 修改 Model 之後要如何更新到 Database

Django 如果 Model裡面的欄位有更動時,即使執行

$ python manage syncdb

是不會更動已經存在的 database 的 Table。

在這StackOverflow討論串有提到像是用 South等Migration Tool,但如果Model只是新增一些Optional的欄位時,這真的是用牛刀了。裡面有提到另一個方法,我覺得還不錯簡單,在此記錄一下:

先用 dumpdata 這個指令把DB的資料先輸出成 .json 的格式。要注意的事,這時侯 model.py 必需是舊的 schema

$ python manage.py dumpdata <APP_NAME> >> /tmp/old_data.json

然後先把資料清掉

$ python manage.py sqlclear <APP_NAME> | python manage.py dbshell

此時就可以修改 models.py 修改欄位,執行 syncdb

$ python manage.py syncdb

最後再把 json 格式的 data 載入回來即可

$ python manage.py loaddata temp_data.json