db.create_all()仅创建缺失表,不更新已有表结构;Flask-Migrate通过Alembic自动对比模型与数据库差异生成迁移脚本,支持安全升级、回滚及团队协作。

直接用 db.create_all() 不能更新已有表结构,改模型后不加迁移,字段增删、类型变更、约束调整全都会被忽略——数据还在,但 schema 落后了。Flask-Migrate 不是“可选项”,而是避免手动写 SQL、错漏回滚、环境不一致的最低成本方案。
为什么 db.create_all() 在已有表时完全失效
SQLAlchemy 的 db.create_all() 只建缺失的表,对已存在的表不做任何 ALTER 操作。哪怕你给 User 模型加了一个 email_verified = db.Column(db.Boolean, default=False),执行 db.create_all() 后数据库里还是没这列。
- 它不比较模型与当前表结构差异,也不生成 DDL
- 开发中反复删库重建会丢数据,生产环境根本不可行
- 多人协作时,A 本地改了字段、B 没同步就跑
create_all,两边 schema 立刻不一致
flask db migrate 怎么知道该生成什么 SQL
它靠 Alembic 的自动对比机制:连接当前数据库,读取现有表结构(通过反射),再和当前 SQLAlchemy 模型定义比对,差什么就记什么。比如发现 users 表缺 email_verified 字段,就生成 op.add_column('users', sa.Column('email_verified', sa.Boolean(), nullable=True))。
- 默认启用
compare_type=True,能检测String(50) → String(100)这类长度变更 - SQLite 下自动启用
render_as_batch=True,绕过原生不支持ALTER COLUMN的限制 - 但它不会自动处理索引重命名、外键约束变更等复杂操作,这类得手写迁移脚本
不加 flask db upgrade 就等于没改数据库
flask db migrate 只生成 Python 脚本(在 migrations/versions/ 下),真正执行 DDL 的是 flask db upgrade。这个分离设计是关键:
SkillSub Pro - Python 题解与代码注释双功能技能功能概述SkillSub Pro - Python 题解与代码注释双功能技能是一项面向实际任务的技能,主要用于SkillSub Pro 是一个 Python 题解生成与代码注释的 双功能合体技能 ,专为学生、算法学习者和开发者设计;✅ 一个技能,两种用途 :;核心要点📝 题解模式 :输入题目/题号,自动生成完整 Python 题解(含详细注释、解题思路、复杂度分析);💬 注释模式 :输入 Python 代码,自动添加详细中。它将相关步骤、
立即学习“Python免费学习笔记(深入)”;
- 脚本可提交 Git,团队共享、Code Review、回溯历史
- 上线前可先在测试库跑
upgrade验证,再推生产 - 出问题时用
flask db downgrade -1回退上一个版本,不用翻备份 - 注意:
upgrade默认作用于head,不是最新脚本——它按down_revision/revision链式执行,跳步或乱序会失败
Flask-Migrate 和原生 Alembic 的实际差别在哪
本质是封装层,但封装解决了几个真实痛点:
- 不用手写
env.py里的get_engine()和run_migrations_online(),Migrate(app, db)自动注入 Flask 应用上下文 - 命令统一进
flask db,不用记alembic revision --autogenerate和alembic upgrade head - 多数据库支持开箱即用(
flask db migrate --multidb),Alembic 原生要自己配多个script_location - 参数如
compare_type、render_as_batch默认开启,而 Alembic 默认关着——尤其 SQLite 用户不设render_as_batch,add_column直接报错
最常被忽略的是:迁移脚本生成后必须人工检查。Alembic 对外键删除、列重命名、JSON 类型变更等识别不准,flask db migrate -m "add email_verified" 输出的脚本里可能漏掉 nullable=False 或默认值逻辑,直接 upgrade 可能导致空值插入失败。

















