使用TypeORM upsert操作PostgreSQL部分索引时遇错误求助
TypeORM Upsert 部分唯一索引报错“column (deleted = FALSE) does not exist”的解决办法
问题场景
我有一个PostgreSQL表,创建了如下部分唯一索引:
CREATE UNIQUE INDEX my_unique_index ON my_table USING btree (cola, colb) WHERE deleted = FALSE;
使用原生SQL执行Upsert操作正常:
INSERT INTO my_table (cola, colb) VALUES ('a', 'b') ON CONFLICT (cola, colb) WHERE deleted = FALSE DO UPDATE SET cola = EXCLUDED.cola, colb = EXCLUDED.colb;
但使用TypeORM的upsert方法时,抛出错误“column (deleted = FALSE) does not exist”,代码如下:
this.repo.upsert( { cola: 'a', colb: 'b' }, { skipUpdateIfNoValuesChanged: true, conflictPaths: ['cola','colb'], indexPredicate: 'deleted = FALSE', } )
解决办法
直接指定部分唯一索引的名称,替代conflictPaths和indexPredicate参数:
this.repo.upsert( { cola: 'a', colb: 'b' }, { skipUpdateIfNoValuesChanged: true, indexName: 'my_unique_index', } )
原因说明
使用conflictPaths + indexPredicate的组合时,部分版本的TypeORM会错误解析谓词表达式,生成的SQL会把indexPredicate的内容当作列名处理,从而触发列不存在的错误。直接指定索引名称indexName可以让TypeORM精准匹配对应的部分唯一索引,生成正确的ON CONFLICT子句。
若你必须使用conflictPaths和indexPredicate的组合,请确保升级TypeORM到最新稳定版本(如0.3.x及以上),旧版本对部分索引的Upsert支持存在bug。
内容的提问来源于stack exchange,提问作者Joey Allgaier
相关产品推荐
相关产品推荐

