为什么需要数据库迁移?¶
在开发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的繁琐,又能保证数据安全,是开发中必不可少的工具!