iT邦幫忙

2021 iThome 鐵人賽

DAY 14
0
Modern Web

Flask系列 第 14

Day 14 實作 database migration

前言

昨天講完了 manage.py 跟我們新加入的幾個自訂指令,今天我們還是離不開 manage.py,而且昨天引入但是沒有用到的 db 也要登場了。

今天要登場的是 database migration,它是用來更新資料庫結構的,可以想成資料庫的版本控制。

初始化

我們要先在 manage.py 裡面加入以下幾行。

from flask_migrate import Migrate
migrate = Migrate(app, db, render_as_batch=True)

這樣就完成了,現在我們可以使用 flask 指令來處理資料庫的變化了。

flask db

在開始之前,我們要先把 data.db (之前生出來的資料庫檔案) 刪掉,然後重新開始。

最一開始,我們需要先初始化,要使用 flask db init,他應該會跑一下下,然後生出一個叫做 migration/ 的目錄,但現在裡面還沒甚麼內容。

接著我們要使用 flask db migrate -m "description" 來建立一個版本,-m 後面要加上這個版本的說明之類的,有點像 git 的感覺。而這個版本的來源是我們的 models.py,而不是現在資料庫的樣子。這樣一來,他就會生出一個新的版本,放在 migration/versions/ 裡面,他會有一個獨特的編號,像 git 每一個 commit 都有編號一樣。

但建好這個版本之後,我們資料庫還沒有跟上,必須要使用 flask db upgrade 來把它升級到新版本,理論上第一個版本應該是建立好三個 table。這時候打開資料庫,應該會看到裡面已經有建好的 table,然後還有外加一個 Flask-Migrate 在用的 table。

我們現在可以嘗試在這個資料庫裡面加入一些資料,加入文章跟留言會被昨天提到的外鍵卡到,所以我們加入一個新的使用者來當作範例,看等等建立新版並且升級之後這筆資料會發生甚麼事。

接著我們到 models.py 稍微調整一下資料庫結構,我們嘗試加入一個 test = db.Column(db.String)Users 裡面。現在我們的 models.py 已經更動了,所以我們可以建立新的版本,再次使用 flask db migrate,這時候應該可以看到他會說偵測到有加入的 column,然後一個新版本就建好了。在升級之前我們可以看看一些小東西。flask db current 會讓你知道你現在在哪個版本,而 flask db heads 則會讓你知道現在的最新版本。

看完之後應該就可以看到 currentheads 是不一樣的,所以這時候就可以再來 flask db upgrade,讓他升級上去。最後我們打開資料庫,應該會看到 users 這個 table 已經更新了,加入了一個新的欄位,但同時舊的資料也沒有被刪除。

當然,這是一個測試用的版本,我們不會留在這個版本做事,所以我們要用 flask db downgrade 來退回前一個版本。在最一開始的初始化中,我們加入了一個 render_as_batch 的參數,會加入他是因為我們開發中先使用 sqlite,但他遇到刪除欄位的時候會爆炸,加上這個參數之後他就會換個方式,會變成把本來的資料庫砍掉然後重建,再把舊的資料複製過去新的,所以就可以避免掉 sqlite 不讓我們刪除的問題。

References

實作 Flask-Migrate更新資料庫
DAY26-搞懂Flask-Migrate
Flask實作 ext 06 Flask-Migrate
Why Flask-migrate cannot upgrade when drop column
Sqlite lack of ALTER support, Alembic migration failing because of this. Solutions?


上一篇
Day 13 實作 manage.py
下一篇
Day 15 實作測試 (1)
系列文
Flask30

尚未有邦友留言

立即登入留言