ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Immich 数据库迁移:schema 变更如何经由 sql-tools 落到 PostgreSQL

2026/9/8 23:40:32 拓冰建站 浏览量
Immich 数据库迁移:schema 变更如何经由 sql-tools 落到 PostgreSQL Immich 数据库迁移schema 变更如何经由 sql-tools 落到 PostgreSQL【免费下载链接】immichHigh performance self-hosted photo and video management solution.项目地址: https://gitcode.com/GitHub_Trending/im/immich你在server/src/schema里给users表加了个字段提交代码、重启服务却发现数据库里根本没有这个列。Immich 的数据库迁移机制就是为这个断层设计的声明式 schema 代码不会直接改库一切变更必须经由 sql-tools 生成的迁移文件落到 PostgreSQL。读完这篇你能独立完成一次 schema 变更生成迁移、登记 ORDER 清单、回滚与诊断出错时还能重建本地库。三层架构声明、脚本与清单各管什么Immich 的 schema 全部放在server/src/schema拆开看是三层。tables/当前仓库共 64 个声明式表定义文件如asset.table.ts、album.table.ts用immich/sql-tools的 API 描述数据库应该长什么样。enums.ts与functions.ts枚举和数据库函数、触发器定义。migrations/96 个毫秒时间戳命名的迁移文件外加一个ORDER清单。文件里的up()/down()才是把已有数据库改成那样的执行单元。immich/sql-toolsworkspace 中锁定 0.6.3是连接声明与真实库的桥它比对声明式 schema 与数据库当前状态的差异生成迁移 SQL并在需要时按清单顺序执行。官方对完整流程有说明可参考 database-migrations.md。完整走一遍变更给 users 表加 avatarColor 列假设你要把用户头像颜色从user_metadata的 JSON 里提出来做成users表的一个正式列。先改tables/user.table.ts里的声明——但只改声明数据库不会有任何变化接下来才轮到迁移登场。生成迁移文件的命令封装在 server/mise.toml 里[tasks.migrations] env._.path ./node_modules/.bin run sql-tools -u ${DB_URL:-postgres://postgres:postgreslocalhost:5432/immich} migrations也就是说mise //server:migrations generate name实际展开为sql-tools -u 连接串 migrations generateDB_URL未设置时默认连本地 Docker 开发环境里的 Postgres。sql-tools 会读取你刚改的声明、比对真实库把差异写成带时间戳前缀的.ts文件。生成后先别急着用人工审阅up()和down()两件事DDL 是否符合预期、down能否安全回退、存量数据有没有回填。仓库里的AddUserAvatarColorColumn迁移就是个好范本裁剪后长这样export async function up(db: Kyselyany): Promisevoid { await sqlALTER TABLE users ADD avatarColor character varying;.execute(db); await sqlUPDATE users SET avatarColor user_metadata.value-avatar-color FROM user_metadata WHERE users.id user_metadata.userId AND user_metadata.key preferences;.execute(db); } export async function down(db: Kyselyany): Promisevoid { await sqlALTER TABLE users DROP COLUMN avatarColor;.execute(db); }up先加列、再从 JSON 元数据回填存量数据down只负责删列因为回填的数据已无保留必要。审完把文件移入server/src/schema/migrations——generate 的产物并不直接落在最终目录。最后执行登记mise //server:migrations generate AddUserAvatarColorColumn mise //server:migrations sync-ordersync-order会把新迁移名去掉.ts后缀追加进 migrations/ORDER 清单。注意这一步会改动清单文件本身所以 ORDER 必须连同迁移文件一起提交否则别人拉走你的分支也会少这一条记录。ORDER 清单为什么必须进 gitserver/src/schema/migrations/ORDER 每行一个迁移名从1744910873969-InitialMigration一路排到最新一条。它存在的理由只有在分支合并的视角下才看得清。假设两条分支各自新增了迁移A 分支的迁移依赖 B 分支刚建的表。如果顺序只靠目录里的时间戳文件决定两个分支合并时文件互不冲突静默地按各自时间戳排进同一目录——而时间戳只反映创建时刻不反映依赖关系。谁先被执行谁的 DDL 就可能引用一张不存在的表最终所有拉到合并结果的人都在启动阶段翻车。把 ORDER 纳入 git 之后两个分支的迁移都会往这个文件的同一处追加合并必然产生冲突。你被强制停下来手工解冲突显式决定谁排在前、谁排在后。代价是每次合并多解一次冲突换来的是执行顺序永远有据可查。verify-order子命令则负责校验磁盘上的迁移文件与清单逐条一致防止有人提交了迁移却忘了sync-order。出错的两条路revert 回滚 与 schema-check 漂移诊断验证down逻辑是否真的可逆时直接回滚最新一条mise //server:migrations revert它执行最新迁移的down()把 schema 恢复到迁移前。sql-tools还支持 run、revert、verify-order 等子命令server/package.json 里另有一组migrations:*npm scripts 与之等价可以直接在 server 目录内调用。回滚解决的是最后一步做错了另一种情况更隐蔽库的实际状态和迁移历史对不上。这时用服务端的schema-check命令实现见 schema-check.ts。它把每个迁移归为三态applied已应用正常路径、deleted数据库里应用过磁盘文件却不见了、missing磁盘上有文件库里没应用。检测到 schema 漂移时命令会列出漂移项并附一段自动生成的修复 SQL——源码里专门标注了 Use at your own risk!意思是这段 SQL 仅供参考执行前必须人工确认。本地库彻底乱了schema-drop 与 schema-reset 一键重建如果漂移报告怎么修都理不清——手工改过表、误删过迁移文件——最可靠的恢复手段是直接重建。mise.toml 里有两个任务都只应出现在开发环境[tasks.schema-drop] run { task migrations query DROP schema public cascade; CREATE schema public; } [tasks.schema-reset] run [ { task :schema-drop }, { task migrations run } ]schema-drop用DROP SCHEMA public CASCADE清空后重建空 schema数据全没schema-reset在此之上按 ORDER 清单重放当前仓库的全部 96 个迁移得到与代码完全一致的干净库。生产环境绝对不要碰这两个任务。其实不用手动 run启动自动应用CI 兜底开发流程里手动执行迁移的时机比你想象的少。服务端的启动流程本身就包含运行所有未应用的新迁移这一环节而开发环境里 server 监听*.ts文件变化并自动重启所以迁移文件落进migrations目录、热重载一次新迁移立刻应用无需手动 run。CI 侧则有兜底server/mise.toml 的checklist任务在单测和中测之后还会执行verify-order清单与文件不一致就挡下提交。手动 run 更多是留给调试场景——比如想在重启服务前单独跑一遍迁移。提交前自检tables/的声明与up()生成的 DDL 是否一致down()能完整回退存量数据回填没有遗漏迁移文件已移入server/src/schema/migrationssync-order已执行ORDER 与迁移文件一起提交本地重启 server 后迁移自动应用schema-check无漂移。【免费下载链接】immichHigh performance self-hosted photo and video management solution.项目地址: https://gitcode.com/GitHub_Trending/im/immich创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考