使用peewee_migrate來進行數據庫結構的自動遷移

        因爲工作需要,使用的orm工具爲peewee。peewee號稱輕量級的orm,果然不假,核心代碼就四千多行,也滿足了工作的基本要求。可是peewee不像SQLAlchemy有alembic或者Django有South,peewee沒有自動對數據庫進行DDL語句升級的工具。其在playhouse自帶了一個手動的migrator,留着以後擴展用的。但身爲程序員怎麼能忍受手動的事情呢?本着能躺着就不坐着的心態,能自動的就讓他自動唄。於是上github搜索,果不其然,人家已經造好輪子了,peewee_migrate。今天就來聊聊怎麼使用它,具體文檔他的github也有,大家可以自行去看看。


首先我們先用peewee創建一個model.py:

import peewee as pw

db = pw.MySQLDatabase(
    host='127.0.0.1', user='root', passwd='password', database='pw_migrate', charset='utf8')


class BaseModel(pw.Model):
    class Meta:
        database = db


class Person(BaseModel):
    name = pw.CharField()
    birthday = pw.DateField()
    is_relative = pw.BooleanField()

class Pet(BaseModel):
    owner = pw.ForeignKeyField(Person, related_name='pets')
    name = pw.CharField()
    animal_type = pw.CharField() 

然後我們使用peewe_migrate來創建表pw_migrate.py:

import model
from peewee_migrate import Router

model.db.connect()

router = Router(model.db)

router.create(auto=model)
router.run()

model.db.close()

運行pw_migrate.py,會生成一個001_auto.py的文件,用於遷移的。上面的命令中就是用router.create(auto=model)來生成這個文件的。然後使用router.run()來操作數據庫,生成相應的表。其中生成的表中有一張名爲migratehistory,是用來記錄你遷移成功了哪些文件。如果你按我上面那樣進行,如無意外會有多一張表:basemodel,很明顯我們並不想要生成他,所以可以這樣做。

router = Router(model.db, ignore='basemodel')

這樣便不會生成basemodel這張表,當然peewe_migrate 也提供rollback功能:

router.rollback('001_auto')

如果你在上一步生成了basemodel這張表會無法rollback的,只能註釋調001_auto.py文件的相應部分,並且手動刪除這張表。

講了這麼多,纔到我們真正主要的部分,自動遷移。跟alembic或者South一樣,你只需要修改你的model部分就可以進行遷移了。

class Pet(BaseModel):
    owner = pw.ForeignKeyField(Person, related_name='pets')
    name = pw.CharField()
    animal_type = pw.CharField()
    birthday = pw.DateField(null=True)

在運行pw_migrate.py原來的pet表就會多了birthday字段了。一切如此簡單,真是愜意。當然peewee_migrate的代碼也寫的很不錯,並且代碼量不多,如果你對peewee足夠熟悉可以上去閱讀學習。

另外,如果你的數據庫已經有了數據,且不想刪除它,可以這樣:

router.run(fake=True)

這樣可以避免重複創建已有表的錯誤。

當然peewee_migrate還在不斷進行維護和更新當中,使用過程中會不少bug,比如說,尚未支持聯合外鍵的創建字段的約束也無法自動生成,當然像rename這些都是要手動的,不然會導致數據的丟失,因爲自動生成的操作是刪除舊的字段,重新生成你所重命名的字段。如果使用 from peewee import * 也會遷移失敗。還有現在還不支持外鍵的更改,主要是peewee那邊的外鍵更改支持有bug。

在我fork的分支上針對mysql支持的以上的內容,github。當然你要配套裏面的peewee才能支持外鍵更改,另外對DateField支持datetime.datetime.now的創建。

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