爲什麼需要數據庫遷移?¶
在開發Web應用時,數據庫結構(比如表結構、字段類型)可能會隨着需求變化而調整。如果直接手動修改數據庫文件(比如SQL文件),可能會導致數據丟失,或者在多人協作時版本混亂。數據庫遷移工具的作用就是安全地修改數據庫結構,同時保留已有數據,就像“給數據庫做版本控制”。
什麼是Flask-Migrate?¶
Flask-Migrate是Flask生態中一個簡化數據庫遷移的工具,它基於Alembic(SQLAlchemy的遷移框架)開發,專門用於管理Flask應用與SQLAlchemy結合的數據庫結構變更。它能自動生成遷移腳本,並將腳本作用到數據庫,避免手動寫SQL語句的麻煩。
安裝與初始化¶
1. 安裝依賴¶
首先確保已安裝Flask和Flask-SQLAlchemy(數據庫ORM工具),然後安裝Flask-Migrate:
pip install flask flask-sqlalchemy flask-migrate
2. 初始化Flask應用與數據庫¶
創建一個簡單的Flask應用(例如app.py),並初始化數據庫和遷移工具:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
# 初始化Flask應用
app = Flask(__name__)
# 配置數據庫(以SQLite爲例,也可替換爲MySQL/PostgreSQL)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # 關閉不必要的修改跟蹤
# 初始化SQLAlchemy
db = SQLAlchemy(app)
# 初始化Flask-Migrate(必須在db初始化後執行)
migrate = Migrate(app, db)
# 定義模型(後續會演示模型變更)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
if __name__ == '__main__':
app.run(debug=True)
核心遷移命令(必學!)¶
Flask-Migrate通過Flask命令行工具執行遷移,需先設置環境變量指定應用入口:
# Linux/Mac
export FLASK_APP=app.py # app.py爲你的應用文件名
# Windows(PowerShell)
$env:FLASK_APP = "app.py"
之後即可使用以下命令:
1. 初始化遷移環境(第一次執行)¶
當你第一次使用Flask-Migrate時,需要先初始化一個存放遷移腳本的文件夾:
flask db init
執行後會在項目根目錄生成一個migrations文件夾,裏面包含遷移相關的配置文件和腳本模板。
2. 生成遷移腳本¶
當你修改了數據庫模型(例如新增/修改字段),需要生成一個遷移腳本,說明“要做什麼變更”:
flask db migrate -m "描述變更內容"
-m參數:必填,用於描述本次遷移的目的(比如"add age field to User model")。- 執行後,
migrations/versions文件夾下會生成一個Python文件(如xxxxxxxx_add_age_field_to_user_model.py),裏面記錄了模型變更對應的SQL語句。
3. 應用遷移到數據庫¶
生成腳本後,需要將腳本中的SQL語句“應用”到數據庫,使結構變更生效:
flask db upgrade
執行後,數據庫會自動更新表結構(例如新增的age字段會被添加到User表中)。
實戰演示:從0到1的遷移流程¶
假設我們需要逐步完成以下需求:
階段1:首次創建User表¶
- 初始化遷移環境:執行
flask db init,生成migrations文件夾。 - 生成首次遷移腳本:修改
User模型後,執行flask db migrate -m "create User table"。
- 此時migrations/versions下會生成一個腳本,內容是創建User表的SQL。 - 應用遷移:執行
flask db upgrade,數據庫中會創建User表。
階段2:修改模型(新增字段)¶
假設需求變化,需要給User表新增一個age字段:
1. 修改模型:在app.py中更新User類:
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
age = db.Column(db.Integer) # 新增字段
- 生成新遷移腳本:執行
flask db migrate -m "add age field to User"。
- 此時migrations/versions會生成新的腳本,內容是ALTER TABLE user ADD COLUMN age INTEGER。 - 應用新遷移:執行
flask db upgrade,age字段會被自動添加到數據庫表中。
撤銷遷移(瞭解即可)¶
如果遷移出現問題或需要回滾,可使用downgrade命令撤銷最近一次遷移:
flask db downgrade
注意:只有在遷移腳本中明確寫了“撤銷邏輯”時,downgrade纔有效(Flask-Migrate通常會自動生成)。
常見問題與新手注意事項¶
-
migrations文件夾已存在?
如果flask db init報錯(提示migrations已存在),說明你可能重複執行了初始化。此時無需刪除文件夾,直接跳過init,繼續執行migrate和upgrade即可。 -
遷移腳本衝突?
若多人協作或多次修改後腳本衝突,可檢查migrations/versions下的腳本,手動合併SQL語句(但新手建議優先用版本控制隔離修改)。 -
SQLite與MySQL的區別?
本文以SQLite爲例(無需額外配置數據庫),若使用MySQL/PostgreSQL,只需修改SQLALCHEMY_DATABASE_URI(例如mysql+pymysql://user:pass@localhost/dbname),遷移邏輯完全一致。
總結¶
Flask-Migrate的核心是“模型變更→生成腳本→應用數據庫”的閉環流程,通過簡單的命令即可安全管理數據庫結構。記住以下3步,新手也能輕鬆上手:
- 改模型:修改
db.Model中的字段或表結構。 - 生成腳本:用
flask db migrate -m "說明"生成遷移文件。 - 應用變更:用
flask db upgrade讓數據庫生效。
這樣既能避免手動寫SQL的繁瑣,又能保證數據安全,是開發中必不可少的工具!