
Immich 数据库迁移实战从加一列到一键回滚【免费下载链接】OpenCore-Legacy-PatcherExperience macOS just like before项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-PatcherImmich 是一款自托管的照片/视频管理项目服务端把所有业务数据存在 PostgreSQL 里。只要改过表结构必须走一次数据库迁移数据库才会真正生效。这篇文章从想给表加一列字段这个最常见的需求切入把生成迁移、审读内容、登记 ORDER 清单、自动应用、回滚与漂移排查的整条链路走一遍并附上命令速查表和提交前检查清单。Immich schema 变更之前分清 schema、migrations、ORDER 的分工拿装修打比方。server/src/schema/tables/下的表定义文件约 64 个表外加负责枚举与数据库函数的enums.ts、functions.ts是设计图纸描述数据库应该长什么样migrations/目录里一个个时间戳-名称.ts文件是施工方案up()负责把现有库改成图纸的样子down()负责退回去migrations/ORDER则是施工排期表固定各套方案的先后顺序。immich/sql-tools是连接图纸和工地的勘察队它拿声明式 schema 去对照真实数据库从差异里自动生成迁移 DDL运行时再按 ORDER 的顺序执行。这个工具在仓库锁文件中锁定为 0.6.3。schema图纸server/src/schema/下的声明式定义描述目标状态migrations施工方案每次变更一个.ts毫秒时间戳前缀保证字典序即执行顺序ORDER排期表受 git 跟踪的清单决定谁先谁后是多分支合并不乱序的关键。Immich 迁移实战给表一列字段的完整流程生成迁移文件的正确姿势先说结论在 monorepo 根目录执行mise //server:migrations generate AddNewField就能生成迁移文件。//server:前缀表示在 monorepo 根目录下执行server包的任务mise.toml声明了monorepo_root true。server/mise.toml里这个任务实际展开为sql-tools -u 连接串 migrations generate name连接串取自环境变量DB_URL不设置时默认指向postgres://postgres:postgreslocalhost:5432/immich也就是本地 Docker 开发环境里的 Postgres。生成的文件以毫秒时间戳-PascalCase名称.ts命名先落在 server 目录下此时还没进最终目录审读通过后再移过去。审读 up 与 down三个必查点打开生成的文件依次查三件事。第一DDL 是否符合预期列名、类型、可空性都对不对是不是加在了你打算改的表上。第二存量数据要不要回填新列加完老行都是空的想从已有字段填充就得在 ADD 之后自己补 UPDATE工具生成的 DDL 只改结构、不动数据。第三down能不能安全回退涉及删列、覆盖数据这类不可逆步骤必须显式接受数据丢失才允许合入。拿仓库里早期的1744991379464-AddNotificationsTable来说up是一套建表语句down就是对应的删表方向严格相反。仓库里还有一些空操作占位迁移比如1750323941566-UnsetPrewarmDimParameter它的up/down什么都不做存在的意义只是维持 ORDER 清单与磁盘文件的一一对应别随手删。登记 ORDER 清单别漏了这一步审读完成后把迁移文件移进server/src/schema/migrations/再执行mise //server:migrations sync-order把它的名字去掉.ts后缀追加进 ORDER 清单。ORDER 为什么必须和迁移一起提交设想两个分支各自新增了一条迁移如果只靠目录里的时间戳文件合并后两条迁移会静默地以错误顺序执行——某条 DDL 依赖的表对方还没建服务启动直接失败。ORDER 进了 git两边各追加一行合并必然冲突逼着你显式定好先后顺序这是用冲突噪音换顺序确定性。自动应用与 CI 校验重启即生效开发环境不用手动执行迁移。服务端会监听.ts文件变化自动重启而启动流程本身就包含应用所有未执行的新迁移这一步——保存文件、等它重启迁移就落到本地库里了。CI 侧checklist 任务在单测和中测之后还会执行一次verify-order确认磁盘上的迁移文件与 ORDER 清单一一对应专门拦住忘了 sync-order这类提交。Immich 迁移回滚与漂移排查本地库状态和迁移历史对不上了怎么办下面三个工具从轻到重。迁移回滚命令revert 只回退一步它只做一件事执行最近一次已应用迁移的down()把 schema 退回到迁移前。命令是mise //server:migrations revert最适合用来验证你刚写的down逻辑是否真的可逆。注意它只回一步不是批量撤销。schema-check 漂移检测三种状态判定手工改过表、误删过迁移文件时跑 schema-check 服务命令核对磁盘迁移与数据库实际状态。每个迁移会被归入三种状态之一applied已应用、deleted数据库里已应用但磁盘文件没了、missing磁盘上有但还没应用。检测到漂移时它会列出漂移项并附一段自动生成的修复 SQL。源码里明确标注了Use at your own risk——这段 SQL 仅供参考执行前务必逐行人工确认。本地数据库一键重建drop 与 reset最后一招是重建本地库。server/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先清空publicschemaschema-reset在此基础上按 ORDER 顺序重放全部 97 个迁移得到一个与代码完全一致的干净库。⚠️警示这两个操作仅限开发环境使用会清空全部数据严禁对生产库执行。命令速查表mise 任务与 npm scriptsmise 任务monorepo 根目录npm scriptserver 目录作用mise //server:migrations create namemigrations:create创建空迁移骨架mise //server:migrations generate namemigrations:generate比对 schema 与数据库差异自动生成迁移 DDLmise //server:migrations runmigrations:run执行所有未应用的迁移mise //server:migrations revertmigrations:revert回滚最近一次迁移mise //server:migrations sync-ordermigrations:sync-order把新迁移登记进 ORDER 清单mise //server:migrations verify-ordermigrations:verify-order校验清单与磁盘文件一致CI 使用另有一个migrations:debug等价于generate附带调试输出。避坑清单五个高频问题生产环境禁用 drop / reset。DROP SCHEMA public CASCADE会清掉全部业务数据本文的一键重建只适用于本地开发库。先确认DB_URL可达。generate、run 类命令都会连真实数据库读取现状连接串不通时要么报错要么比对出错误的差异。工具版本以仓库锁文件为准。immich/sql-tools锁定在 0.6.3自行全局装最新版再跑命令生成的 DDL 可能和仓库对不上。ORDER 与迁移文件同一次提交。漏了sync-orderverify-order会直接让 CI 变红反过来只提交 ORDER 不提交文件同样不行。空操作迁移文件别乱删。它维持着 ORDER 与磁盘文件的一一对应删掉后数据库侧会把对应记录判成deleted。提交前过一遍这五条审读迁移的up/downDDL 符合预期、存量数据已回填、回退安全迁移文件已移入server/src/schema/migrations/执行sync-orderORDER清单随本次提交一起提交重启本地 server确认迁移自动应用成功跑一遍verify-order通过后再推送。【免费下载链接】OpenCore-Legacy-PatcherExperience macOS just like before项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考