在使用Flask開發Web應用時,數據庫結構的變化是常見需求。比如新增字段、修改表結構、調整字段類型等。如果直接手動修改數據庫,不僅容易出錯,還可能導致數據丟失。這時候,數據庫遷移工具就派上用場了。Flask-Migrate就是專門爲Flask設計的數據庫遷移擴展,它基於Alembic實現,能幫助我們安全、方便地管理數據庫結構的變更。
爲什麼需要數據庫遷移?¶
假設你已經通過SQLAlchemy定義了一個User模型,此時數據庫中生成了users表。如果突然想給User模型添加一個age字段(比如年齡),直接在Python代碼中改模型是不夠的——數據庫表結構並沒有同步更新。手動執行ALTER TABLE語句可能會有風險(比如數據類型不匹配、索引丟失)。而數據庫遷移工具可以自動生成遷移腳本,將模型的變更安全地應用到數據庫中。
Flask-Migrate是什麼?¶
Flask-Migrate是Flask的擴展,它封裝了Alembic的核心功能,讓數據庫遷移變得簡單。它與Flask-SQLAlchemy配合使用,通過檢測模型類的變化自動生成遷移腳本,並管理這些腳本的執行(升級/回滾)。
安裝與配置¶
首先確保已安裝必要的庫:
# 安裝Flask-Migrate
pip install flask-migrate
# 假設已安裝Flask和Flask-SQLAlchemy(如果沒裝,先執行)
pip install flask flask-sqlalchemy
在Flask應用中初始化Flask-Migrate:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mydatabase.db' # 數據庫連接
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
migrate = Migrate(app, db) # 初始化遷移工具,關聯app和db
# 定義模型(示例)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
# 路由和其他代碼...
數據庫遷移核心命令¶
Flask-Migrate將Alembic的命令封裝成了Flask CLI命令,常用命令如下:
| 命令 | 作用 |
|---|---|
flask db init |
初始化遷移環境(只執行一次,生成migrations文件夾和versions目錄) |
flask db migrate -m "描述" |
生成遷移腳本(-m指定腳本說明,如“add age field to User”) |
flask db upgrade |
應用遷移腳本,更新數據庫結構 |
flask db downgrade |
回滾最近一次遷移(如果需要撤銷) |
完整遷移流程示例¶
1. 初始化遷移環境¶
在項目根目錄執行:
flask db init
執行後會生成一個migrations文件夾,包含versions目錄(存放遷移腳本)和env.py等配置文件。
2. 第一次模型遷移¶
假設此時我們有一個User模型(見上文代碼),需要將其映射到數據庫:
# 生成遷移腳本
flask db migrate -m "create users table"
# 應用遷移腳本到數據庫
flask db upgrade
此時,數據庫(mydatabase.db)中會自動創建users表,結構與User模型一致。
3. 修改模型並重新遷移¶
如果需要給User模型添加age字段:
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
age = db.Column(db.Integer) # 新增age字段
然後重複遷移流程:
# 生成新的遷移腳本(檢測到模型變化)
flask db migrate -m "add age field to User"
# 應用新遷移,數據庫表會自動添加age字段
flask db upgrade
4. 回滾遷移(如果出錯)¶
如果遷移後發現問題,比如age字段定義錯誤(如應該允許爲空但設爲nullable=True卻寫成False),可以回滾:
# 回滾最近一次遷移
flask db downgrade
# 檢查遷移記錄:versions目錄中會保留歷史版本,回滾後versions中的最新遷移被撤銷
進階技巧:處理複雜遷移¶
如果模型變更涉及數據遷移(如修改字段類型、刪除字段),flask db migrate可能無法自動生成正確的遷移腳本,這時需要手動修改遷移腳本:
- 生成遷移腳本後,檢查
migrations/versions/下的腳本文件(如a1b2c3d45678_add_age_field.py) - 在
upgrade和downgrade函數中手動處理數據轉換,例如:
# 假設修改字段類型爲String,且需要設置默認值
def upgrade():
op.add_column('users', sa.Column('age', sa.String(), nullable=True))
# 手動添加默認值(如果需要)
op.execute("UPDATE users SET age = '20' WHERE age IS NULL")
總結¶
Flask-Migrate通過以下步驟解決了數據庫遷移問題:
1. 初始化遷移環境:flask db init
2. 生成遷移腳本:flask db migrate -m "描述"
3. 應用/回滾遷移:flask db upgrade / flask db downgrade
核心優勢是自動檢測模型變更、版本控制遷移歷史、安全回滾,避免手動修改數據庫的風險。初學者只需記住上述命令和流程,就能輕鬆管理數據庫結構的迭代。
常用命令速查表:
- 初始化:flask db init
- 生成腳本:flask db migrate -m "描述"
- 應用遷移:flask db upgrade
- 回滾:flask db downgrade
通過不斷實踐,你就能熟練使用Flask-Migrate管理數據庫的每一次變化!