Rust 没有唯一的迁移工具:SQLx、Diesel 和 SeaORM 都有各自方案,Refinery 则独立于 ORM。生产项目的共同默认值是版本化迁移:每次变更保存为新文件或模块,按序执行并记录历史。
先给结论
| 场景 | 推荐 | 选择理由 |
|---|---|---|
| 使用 SQLx,偏 SQL-first | SQLx Migrations | 与连接池、CLI 和 migrate! 集成直接 |
| 使用 Diesel | Diesel migrations | CLI、SQL 迁移和 schema.rs 工作流完整 |
| 使用 SeaORM | SeaORM Migration | 异步迁移 crate,可用 SeaQuery 或 SQL |
| 不想绑定 ORM | Refinery | 独立迁移器,支持 SQL 和 Rust migration |
| 多语言团队需要统一 Schema 治理 | Atlas | 统一生成、检查和管理版本化迁移 |
优先使用当前数据访问层自带的迁移工具。没有 ORM 约束时选 Refinery;只有在确实需要跨语言 diff 和 CI 风险检查时,再考虑 Atlas。
常见方案
SQLx Migrations
SQL-first 迁移,CLI 可执行迁移目录,也可用 sqlx::migrate! 将其嵌入二进制。SQLx 会记录迁移 checksum,发现已执行文件被改动。
- 适合:使用 SQLx、Axum 或 Actix Web,并愿意直接维护 SQL 的项目。
- 注意:嵌入只解决迁移文件随二进制发布,不解决多实例并发。新增文件后要确保重新构建;不要随意更换迁移目录或迁移表配置。
Diesel migrations
以 up.sql / down.sql 为主,提供 CLI、迁移嵌入和 schema.rs 生成。可从 Schema diff 生成迁移草稿。
- 适合:已经使用 Diesel CLI、查询和
schema.rs的项目。 - 注意:生成结果需要人工调整;字段改名、回填和索引构建都涉及业务语义。嵌入迁移同样不提供多实例并发保护。
SeaORM Migration
迁移放在独立 crate 中,可用 SeaQuery 的 Rust API 或原始 SQL 编写,并提供异步 CLI、状态查询和 up/down 操作。
- 适合:使用 SeaORM,且希望迁移和实体代码保持在同一生态的项目。
- 注意:Rust DDL API 有时比 SQL 更冗长;迁移还要登记到
MigratorTrait。生产通常由独立 Job 或 CLI 执行。
Refinery
独立于 ORM 的迁移器,支持 SQL 文件、Rust migration、CLI 和嵌入二进制;会检查迁移历史与 checksum。
- 适合:使用自定义数据访问层,或希望迁移工具不依赖 SQLx、Diesel、SeaORM 的项目。
- 注意:没有传统
down迁移;撤销变更时新增一条向前迁移。它也不会替你同步 ORM 的 Schema 模型。
Atlas
语言无关的 Schema-as-Code 工具,可生成版本化 SQL,并在 CI 中检查部分危险变更。
- 适合:Rust 与其他语言共享数据库平台,或希望统一 Schema diff 和 lint 的团队。
- 注意:不是 Rust 项目的默认迁移库。自动 diff 不理解字段改名、回填等业务语义,生成 SQL 仍需审核。
能力对比
| 方案 | 主要输入 | 可嵌入 / 发布方式 | 回滚方式 | ORM 绑定 | 生产建议 |
|---|---|---|---|---|---|
| SQLx | SQL | migrate! | 可选 .down.sql | SQLx | 适合 |
| Diesel | SQL | embed_migrations! | down.sql | Diesel | 适合 |
| SeaORM | Rust / SQL | 独立 migration crate | up / down | SeaORM | 适合 |
| Refinery | SQL / Rust | embed_migrations! 或 CLI | 新增向前迁移 | 无 | 适合 |
| Atlas | Schema / SQL | 通常由 CI/CD 执行 | 版本化迁移 | 无 | 适合统一治理 |
生产实践
- 迁移只运行一次:用 CI/CD 或单独 Job 执行,不要让每个 Web 实例启动时同时迁移。
- 保持历史不可变:已执行迁移不要修改。
down只能运行反向 SQL,不能恢复被删除的数据;生产故障一般新增修复迁移。 - 分阶段发布风险变更:字段改名或大表改动按“新增兼容结构、回填、切换应用、清理旧结构”分步完成。
- 检查事务和数据库行为:并非所有 DDL 都能放进事务。CI 使用与生产相同的大版本数据库,并检查迁移失败后的实际状态。
参考资料
相关主题:项目选型。