DEBUG.WIKI
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
搬瓦工;先看线路,再选 VPS;CN2 GIA · 对应线路套餐;查看线路 →
V.PS:让项目靠近用户,亚太、欧洲、北美 KVM VPS

jOOQ migrateTo 生成的 DROP INDEX 漏掉 schema,别用 IF EXISTS 掩盖

jOOQ 3.21.9 对 PostgreSQL 生成索引删除迁移时,可能只输出未限定的索引名。核对目标 schema 和生成 SQL,在审核后的迁移中明确限定目标索引,并检查实际对象差异。

PostgreSQL 中的索引明明存在,执行 jOOQ meta.migrateTo() 生成的删除迁移,却提示找不到索引。使用 jOOQ 3.21.9 时,要看生成的 DROP INDEX 是否只剩下索引名,而漏了索引所属 schema。

一个明确场景是 PostgreSQL 18:表为 test.test,索引名为 idx_test,目标元数据只移除该索引。差异迁移可能生成:

DROP INDEX idx_test;

当执行连接的 search_path 不包含 test 时,这条语句不会定位到 test.idx_test。若另一个可见 schema 恰好有同名索引,风险更大,语句还可能定位到错误对象,不能只在开发库“恰好成功”就直接上线。

保留元数据中的索引身份

3.21.9 的差异逻辑将索引传给 DropIndex,后者在 PostgreSQL 的默认路径访问 Index 对象。IndexImpl 把 PostgreSQL 列在不输出索引限定名的方言名单中,渲染时只访问 getUnqualifiedName();这条规则也影响了 DROP INDEX。源元数据有 schema,不代表最终语句仍然带着它。

先保存当前与目标元数据、生成 SQL、jOOQ 版本以及实际数据库方言,确认确实只有预期索引发生变化。也要检查执行迁移的账号和连接目标;生成连接与执行连接采用不同 search_path,会让遗漏限定的语句表现不同。

截至 2026 年 10 月 25 日,可核对的正式 3.21.9 仍有这条渲染路径。3.21.10 等修复目标不能代替实际已发布工件;升级时应核对所选正式版本是否已包含限定名称修正,再比较生成 SQL。

在审核后的迁移中明确 schema

如果迁移已经进入人工审查流程,针对已确认要删除的那个索引,可以把待执行语句写成分段限定的名字:

DROP INDEX "test"."idx_test";

这是删除操作示例,只适用于已经确认该索引应被移除、且具备对应权限的迁移。"test.idx_test" 是一个带点字符的单一标识符,不能代替 schema 与索引名两段。需要动态生成时,使用能够正确处理两段标识符的 API,不把外部输入直接拼进 SQL。

不要全局修改 search_path 来迁就一条缺限定的迁移,也不要简单加 IF EXISTS。后者可能让迁移不报错,却把真正应删的索引留在原处;它也不会消除另一个 schema 存在同名对象的风险。

对自动生成后直接执行的流程,应先增加本次差异的审核与阻断,再选择受支持的改写入口。不要按字符串全局替换所有索引名,生成结果中可能包含不同 schema、引号与大小写组合。

删除语句还有独立的运行约束

普通 DROP INDEX 会获取相关表的强锁。是否允许锁表、是否需要并发删除,属于迁移原有的运行计划;不能为了改 schema 顺手加 CONCURRENTLY。PostgreSQL 对并发删除的事务块、约束索引和其他条件另有限制。

在隔离数据库核对实际生成与执行后的索引集合,尤其包含两个 schema 下同名索引的情况。预期只删除已批准的目标,保留其他索引、表和约束。迁移成功返回后仍需检查实际对象差异;若先前已经执行过错误语句,应先核实数据库现状,再决定是否重做,不盲目重复整份迁移。