系列:Python Web 工程实践
- Python Web 项目配置管理:环境变量、.env 和生产配置怎么拆
- Python Web 项目如何连接数据库:SQLAlchemy、Django ORM、迁移怎么选
- Alembic 数据库迁移入门:表结构变更怎么安全上线
- Django 数据库迁移实战:makemigrations 和 migrate 背后的坑
- FastAPI 项目测试指南:pytest、TestClient、依赖覆盖怎么用
- Django 测试入门:Model、View、API 测试怎么写
- FastAPI 分层架构:router、service、repository 怎么拆
- PostgreSQL 基础:索引、事务、慢查询怎么理解
Alembic 解决的是一个很具体的问题:代码里的模型变了,数据库里的表结构怎么跟着变,而且这个变化要能在开发、测试、生产环境重复执行。
如果你还没决定 ORM,可以先看 Python Web 项目如何连接数据库:SQLAlchemy、Django ORM、迁移怎么选。
初始化 Alembic
在项目根目录执行:
alembic init migrations常见目录会长这样:
migrations/ env.py script.py.mako versions/alembic.iniversions/ 里放每一次迁移文件。env.py 负责加载项目模型和数据库连接。
连接 SQLAlchemy 模型
核心是让 Alembic 知道 Base.metadata。
from app.models import Base
target_metadata = Base.metadata数据库地址不要写死在 alembic.ini 里,可以从项目配置读取。这样本地、测试、生产只需要换环境变量。
from app.config import settings
config.set_main_option("sqlalchemy.url", settings.database_url)生成迁移文件
模型改完后执行:
alembic revision --autogenerate -m "add article table"自动生成只是起点,不是可以直接上线的保证。每次都要打开迁移文件看一遍。
def upgrade() -> None: op.create_table( "articles", sa.Column("id", sa.Integer(), primary_key=True), sa.Column("title", sa.String(length=120), nullable=False), )
def downgrade() -> None: op.drop_table("articles")执行迁移
开发环境执行:
alembic upgrade head查看当前版本:
alembic current查看历史:
alembic history上线前重点检查什么
我最关注这几类改动:
- 大表新增非空字段
- 字段改名被识别成“删除旧字段 + 新增字段”
- 删除字段或删除表
- 创建索引会不会锁表太久
- 默认值是否会触发大量写入
比如字段改名,自动生成经常不可靠。更安全的做法是手动写:
op.alter_column("users", "nickname", new_column_name="display_name")实际上线顺序
比较稳的顺序是:
- 先备份数据库
- 在测试库跑迁移
- 检查应用是否能启动
- 在低峰期执行生产迁移
- 再发布依赖新字段的代码
总结
如果改动大,可以拆成多次迁移。数据库迁移追求的是可恢复、可检查,不是一步到位。每次迁移都应该能解释它改了什么、为什么这样改、失败后怎么处理。