情境
會選擇 Flask-Migrate 純粹是因為我目前是使用 Flask 框架,Flask-Migrate 底層使用 Alembic,Alembic 的作者就是 Mike Bayer,如果用過 SQLAlchemy 應該對他不陌生。
基本上 Alembic 還不能偵測所有改變,像是表格更名、欄位更名、匿名限制等。
但是因為我的需求很簡單,只要能夠讓我的 schema 變更入版控,以及指令調整 schema 即可。
安裝
1 | (venv) $ pip install Flask-Migrate |
使用方式
初始環境
首次使用需要先執行以下指令,來產生 migrations/ 目錄,之後這個目錄要進版控。
1 | $ flask db init |
以我的專案目錄結構為例,會在 mypkg/ 下執行指令產生 migrations/。
1 | myproj/ |
編輯 model
使用 SQLAlchemy ,產生一個 Model,像是:
1 | #!/usr/bin/env python |
產生 migration scripts
1 | $ flask db migrate |
接著只要執行上述指令,就會偵測現有的 model,來動態產生 migration 指令檔,產生出來的指令放在 migrations/versions/ 下。
正如先前所說的,目前還不能偵測得很全面,所以建議打開指令檔檢視與修改。但是如果你的需求跟我一樣單純,那就可以免了。
隨著開發時間拉長,scripts 可能累積很多,那可以考慮全部刪除,然後直接重新執行這個指令,就會把現狀的 schema 濃縮產生到新檔案中。
執行 migration scripts
1 | $ flask db upgrade |
執行了這個指令,才真的是把 scripts 生效到資料庫裡。會自行偵測要改變的項目,目前有:
- table create/delete
- column create/delete
- column nullable state
- basic changes in Indexes and explicitly-named unique constrants
- basic changes in foreign key constraints
如果只是想要單純生成 sql 語句,而不是生效到資料庫,通常是要遞交 sql 給 DBA 執行,可以:
1 | $ flask db upgrade --sql |
help
還可以 downgrade,細部指令可以利用 --help
查詢。
1 | $ flask db --help |
sqlite 惹的麻煩
跟 sqlite 搭配有個小問題,因為 sqlite 不支援 alter
語法,所以當 column 改名的時候,預設情況下執行 upgrade
會報錯。解決方式在這裡有提到,就是編輯 migrations/env.py
黨,加上 render_as_batch=True
這一行即可。
1 | context.configure(connection=connection, |