Flask-Migrate — 数据库迁移
本章你将学会用 Flask-Migrate 安全地管理数据库结构变更,并理解与 Django migration 的对应关系。
为什么不能一直用 db.create_all()?
db.create_all() 有两个致命缺陷:
- 只在表不存在时创建。修改模型(如新增字段),已存在的表不会更新
- 不保留变更历史。无法回滚到之前的数据库状态
数据库迁移 就像数据库的 Git——每次结构变更生成一个版本文件,支持升级和回滚。
Flask-Migrate 是 Alembic 的 Flask 扩展,专为 SQLAlchemy 设计。
安装与配置
(venv) $ pip install flask-migrate
实例
# 文件路径:app.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///blog.db'
db = SQLAlchemy(app)
migrate = Migrate(app, db) # 将 app 和 db 绑定到 Migrate
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///blog.db'
db = SQLAlchemy(app)
migrate = Migrate(app, db) # 将 app 和 db 绑定到 Migrate
迁移三步曲
| 步骤 | 命令 | 作用 | 对标 Django |
|---|---|---|---|
| 初始化 | flask db init | 创建 migrations/ 目录(仅执行一次) | — |
| 生成 | flask db migrate -m "描述" | 检测模型变化,生成迁移脚本 | makemigrations |
| 执行 | flask db upgrade | 将迁移脚本应用到数据库 | migrate |
第一步:初始化迁移目录
(venv) $ flask db init Creating directory migrations/... done
执行后生成 migrations/ 目录(类似 Git 的 .git 目录),只需执行一次。
第二步:生成迁移文件
(venv) $ flask db migrate -m "初始化 Post 和 Category 模型" INFO [alembic.runtime.migration] Context impl SQLiteImpl. Generating migrations/versions/xxxx_initial.py ... done
如果你还没有任何模型变更,直接在已有模型上执行这条命令即可。
第三步:执行迁移
(venv) $ flask db upgrade INFO [alembic.runtime.migration] Running upgrade -> xxxx, 初始化
实战:给 Post 模型新增字段
假设产品需求变更,需要给文章添加一个阅读计数。
实例
# 文件路径:models.py 的 Post 类中新增
class Post(db.Model):
# ... 已有字段 ...
read_count = db.Column(db.Integer, default=0) # 新增:阅读次数
class Post(db.Model):
# ... 已有字段 ...
read_count = db.Column(db.Integer, default=0) # 新增:阅读次数
修改模型后,执行迁移:
(venv) $ flask db migrate -m "Post 模型新增 read_count 字段" (venv) $ flask db upgrade
现在数据库中 posts 表自动增加了 read_count 列,已有数据不受影响。
查看迁移历史
查看当前数据库处于哪个版本:
(venv) $ flask db current
查看所有迁移历史:
(venv) $ flask db history
回滚迁移
迁移是可以撤销的:
(venv) $ flask db downgrade # 回退到上一个版本
这会删除 read_count 列,撤销上一次迁移的所有变更。
不是所有操作都能自动回滚(如删除列在 SQLite 中)。回滚前先确认
flask db current查看当前版本,确保你知道自己在回退什么。生产环境回滚前务必备份数据。
Flask-Migrate vs Django Migration 对照
| 操作 | Flask(Flask-Migrate) | Django |
|---|---|---|
| 初始化 | flask db init | 无需(项目自带 migrations 目录) |
| 生成迁移 | flask db migrate -m "描述" | python manage.py makemigrations |
| 执行迁移 | flask db upgrade | python manage.py migrate |
| 回滚 | flask db downgrade | python manage.py migrate app 0001 |
| 查看历史 | flask db history | python manage.py showmigrations |
| 自动化程度 | 需初始化,检测依赖 Alembic | 全自动,无需额外配置 |
Django 的迁移系统更自动化、更集成;Flask 通过 Flask-Migrate 达到了同等级别的能力。
本章小结
本章你掌握了 Flask-Migrate 的完整流程:flask db init 初始化、flask db migrate 生成迁移脚本、flask db upgrade 执行迁移、flask db downgrade 回滚。
此后每次修改 models.py 都走这个三步流程,数据库结构变更永远有历史可追溯。
