文章列表
2 分钟阅读

Alembic 数据库迁移入门:表结构变更怎么安全上线

更新说明:新增数据库迁移实践文章。


系列:Python Web 工程实践

第 3 / 8 篇

  1. Python Web 项目配置管理:环境变量、.env 和生产配置怎么拆
  2. Python Web 项目如何连接数据库:SQLAlchemy、Django ORM、迁移怎么选
  3. Alembic 数据库迁移入门:表结构变更怎么安全上线
  4. Django 数据库迁移实战:makemigrations 和 migrate 背后的坑
  5. FastAPI 项目测试指南:pytest、TestClient、依赖覆盖怎么用
  6. Django 测试入门:Model、View、API 测试怎么写
  7. FastAPI 分层架构:router、service、repository 怎么拆
  8. PostgreSQL 基础:索引、事务、慢查询怎么理解

Alembic 解决的是一个很具体的问题:代码里的模型变了,数据库里的表结构怎么跟着变,而且这个变化要能在开发、测试、生产环境重复执行。

如果你还没决定 ORM,可以先看 Python Web 项目如何连接数据库:SQLAlchemy、Django ORM、迁移怎么选

初始化 Alembic

在项目根目录执行:

Terminal window
alembic init migrations

常见目录会长这样:

migrations/
env.py
script.py.mako
versions/
alembic.ini

versions/ 里放每一次迁移文件。env.py 负责加载项目模型和数据库连接。

连接 SQLAlchemy 模型

核心是让 Alembic 知道 Base.metadata

migrations/env.py
from app.models import Base
target_metadata = Base.metadata

数据库地址不要写死在 alembic.ini 里,可以从项目配置读取。这样本地、测试、生产只需要换环境变量。

migrations/env.py
from app.config import settings
config.set_main_option("sqlalchemy.url", settings.database_url)

生成迁移文件

模型改完后执行:

Terminal window
alembic revision --autogenerate -m "add article table"

自动生成只是起点,不是可以直接上线的保证。每次都要打开迁移文件看一遍。

migrations/versions/20260206_add_article_table.py
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")

执行迁移

开发环境执行:

Terminal window
alembic upgrade head

查看当前版本:

Terminal window
alembic current

查看历史:

Terminal window
alembic history

上线前重点检查什么

我最关注这几类改动:

  • 大表新增非空字段
  • 字段改名被识别成“删除旧字段 + 新增字段”
  • 删除字段或删除表
  • 创建索引会不会锁表太久
  • 默认值是否会触发大量写入

比如字段改名,自动生成经常不可靠。更安全的做法是手动写:

op.alter_column("users", "nickname", new_column_name="display_name")

实际上线顺序

比较稳的顺序是:

  1. 先备份数据库
  2. 在测试库跑迁移
  3. 检查应用是否能启动
  4. 在低峰期执行生产迁移
  5. 再发布依赖新字段的代码

总结

如果改动大,可以拆成多次迁移。数据库迁移追求的是可恢复、可检查,不是一步到位。每次迁移都应该能解释它改了什么、为什么这样改、失败后怎么处理。