news 2026/6/19 11:58:59

Alembic 数据库迁移

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Alembic 数据库迁移

Alembic 数据库迁移

SQLAlchemy 官方数据库迁移工具,用于 Python 项目的数据库 schema 版本管理。

一、核心概念

  • 迁移文件alembic/versions/下每个.py文件是一个版本,包含upgrade()downgrade()
  • 版本链:每个迁移记录down_revision(依赖的上一个版本),形成线性链
  • alembic_version:数据库中的单行表,记录当前已应用的版本号
  • 每次upgrade head会把未应用的迁移按链顺序执行,并更新alembic_version

二、常用命令

cdserver uv run alembic current# 查看当前版本uv run alembichistory# 查看迁移链uv run alembic check# 检查模型与数据库是否一致uv run alembic revision--autogenerate-m"描述"# 自动生成迁移uv run alembic upgradehead# 应用所有未执行迁移uv run alembic upgrade<rev># 升级到指定版本uv run alembic downgrade-1# 回滚一个版本uv run alembic upgradehead--sql# 输出 SQL 而不执行(> 文件导出)

三、标准工作流

  1. 修改 SQLModel 模型定义
  2. uv run alembic revision --autogenerate -m "描述变更"
  3. 审查生成的迁移文件(autogenerate 非 100% 可靠)
  4. uv run alembic upgrade head应用
  5. 产出增量 SQL:uv run alembic upgrade <上条rev>:head --sql > sql/migration_<日期>.sql

四、server_default 规则

数据库默认值必须在模型中声明(Column(server_default=...)sa_column_kwargs),不能只在迁移文件中手写:

场景写法
时间戳server_default=text("now()")
布尔 falseserver_default="false"
字符串server_default=text("'value'")— 必须用text()防止引号被错误转义

五、迁移压缩(Squash)

5.1 Alembic 无内置 squash 命令

官方没有提供类似 Djangosquashmigrations的功能。

  • alembic merge:用于合并分叉分支(多个 head),创建指向多父节点的交汇迁移,形成菱形结构。这是在加文件而非减文件,与压缩无关。
  • --splice(1.18.5 新增):仅允许merge操作非 head 节点,仍然是分支合并,不是压缩。

Alembic 维护者 zzzeek 在 Discussion #1259 中给出的 squash 方法是:手动 autogenerate 空库法。全量压缩和部分合并原理相同,仅参数不同。

5.2 全量压缩(base → head)

整个链替换为一个初始迁移:

步骤操作
1确保模型与数据库无差异(alembic check
2创建空库,设DATABASE_URL指向空库
3alembic revision --autogenerate -m "initial schema"down_revision = None
4空库上upgrade head验证
5导出init.sql,删旧迁移文件
6开发库UPDATE alembic_version SET version_num = '<新ID>'

5.3 部分合并(链中间段)

只合并中间 B→C→D 为 B’,保留首尾 A 和 E:

A → B → C → D → E (head) └── B' ──┘ (B' 替代 B/C/D,E 接在 B' 后)

关键技巧:空库 schema 跑到 D 状态,但 alembic_version 回退到 A,autogenerate 就会把 A→D 的全部差异生成到一个迁移里。

# 1. 空库先跑到合并起点 A$env:DATABASE_URL="postgresql+asyncpg://.../arbai_squash"uv run alembic upgrade A# 2. 再跑到合并终点 D(schema = D 状态)uv run alembic upgrade D# 3. 回退版本标记到 Apsql-darbai_squash-c"UPDATE alembic_version SET version_num = 'A';"# 4. autogenerate 生成 B'(对比"A 标记" vs "D 实际 schema")uv run alembic revision--autogenerate-m"squash B C D"# 5. 编辑 B':down_revision = 'A'# 6. 编辑 E:down_revision = '<B'的新ID>'# 7. 删除 B、C、D 旧文件# 8. 开发库升级版本标记(如果当前 > D)

六、生产环境部署

Alembic 适合开发环境使用,不适合直接在生产环境执行:

  • Alembic 依赖项目代码和 SQLModel 模型导入,与项目耦合太重,生产部署不应附带完整开发依赖
  • 直接连生产库执行 autogenerate 有风险(误判、连接中断等),且难以审计"实际会执行什么 SQL"
  • 运维团队通常只需要执行确定的 DDL,不需要了解 Python 迁移框架

开发时通过 Alembic 生成增量 SQL 文件,生产环境直接执行 SQL:

首次部署(完整建库):

init.sql

后续升级(增量迁移,按日期顺序执行):

migration_20260616.sql migration_20260620.sql

七、常见坑

7.1 手写迁移与模型不一致

旧手动迁移的 DDL 和 SQLModel 模型定义不一致是常见问题。应始终以模型为唯一数据源,autogenerate 生成迁移。

7.2 字符串 server_default 引号转义

server_default="'active'"→ autogenerate 可能丢失外层引号 → 生成server_default='active'→ SQL 变成DEFAULT active(被当成标识符而非字符串)。

正确做法:模型中使用server_default=text("'active'"),autogenerate 能正确保留。

7.3--sql输出中文乱码

设置环境变量:

PYTHONUTF8=1PYTHONIOENCODING=utf-8 uv run alembic upgradehead--sql>output.sql

7.4 autogenerate 使用 sqlmodel.AutoString

autogenerate 会对Field(max_length=N)的字段生成sqlmodel.sql.sqltypes.AutoString,迁移文件中需import sqlmodel

7.5 布尔 server_default 不需要 text()

server_default="false"对 Boolean 列是正确的 —false在 PostgreSQL 中是布尔字面量,不会被当成标识符。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/19 11:44:09

跑遍10家机构实测!2026教务系统排名,这款实推!

最近 3 个月&#xff0c;我跑10家不同类型教培机构&#xff08;艺术、舞蹈、书法、编程、文化课&#xff09;&#xff0c;跟校长、教务老师深度聊&#xff0c;实地看他们在用什么教务系统、真实感受如何。 结合自己实测体验&#xff0c;整理出2026 教务系统真实排名&#xff0c…

作者头像 李华
网站建设 2026/6/19 11:32:09

用于设计可持续抗侵蚀涂层的高温工具——NanoTest

Micro Materials独创的纳米冲击测试技术旨在产生空间分布的纳米或微米级冲击&#xff0c;以模拟固体颗粒侵蚀&#xff0c;该技术特别适用于研究热障涂层的损伤机制&#xff0c;并在损伤机制和磨损速率方面与侵蚀测试表现出极佳的相关性。这项“随机冲击测试”的专利已获授权&am…

作者头像 李华
网站建设 2026/6/19 11:26:57

抖音批量下载神器:3分钟学会高效采集内容的终极指南

抖音批量下载神器&#xff1a;3分钟学会高效采集内容的终极指南 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback support…

作者头像 李华
网站建设 2026/6/19 11:21:15

深入解析sklearn中PCA的实战应用:从参数调优到结果解读

1. PCA基础与实战价值 主成分分析&#xff08;PCA&#xff09;是机器学习中最常用的降维技术之一&#xff0c;它的核心思想是通过线性变换将高维数据投影到低维空间。想象你手里有一团杂乱无章的毛线&#xff0c;PCA的作用就是帮你找到最能体现这团毛线形状的几个主要方向&…

作者头像 李华
网站建设 2026/6/19 11:18:59

Python跨境数据采集实战:解决地域限制与IP封禁问题(商用稳定方案)

跨境电商、海外资讯、海外竞品数据采集过程中&#xff0c;最影响稳定性的问题并非解析逻辑&#xff0c;而是地域拦截、IP封禁、高频验证码、机房代理低通过率等网络问题。本文基于通用海外住宅代理技术方案&#xff0c;结合 Python 工程化写法&#xff0c;讲解如何搭建一套高可…

作者头像 李华
网站建设 2026/6/19 11:12:08

3分钟找回遗忘QQ号:手机号逆向查询终极指南

3分钟找回遗忘QQ号&#xff1a;手机号逆向查询终极指南 【免费下载链接】phone2qq 项目地址: https://gitcode.com/gh_mirrors/ph/phone2qq 你是否曾因忘记QQ号而无法登录重要账号&#xff1f;或者换了新手机后&#xff0c;只记得手机号却找不到对应的QQ&#xff1f;这…

作者头像 李华