pgp.helpers.update无法更新enum与timestamp字段问题咨询
解决pg-promise中
pgp.helpers.update无法更新enum和timestamp类型字段的问题 问题根源
PostgreSQL对数据类型匹配要求严格,pgp.helpers.update默认生成的VALUES子句会将enum、timestamp类型的值以text格式传递,与目标字段的comparator_type枚举、timestamp类型不匹配,触发42804类型转换错误。
可行解决方案
方法1:用ColumnSet显式指定字段类型
这是最规范的处理方式,通过定义ColumnSet时声明字段对应的PostgreSQL类型,让pg-promise自动生成带类型转换的SQL:
// 定义ColumnSet并指定字段类型 const cs = new pgp.helpers.ColumnSet([ '?id', {name: 'comparator', cast: 'comparator_type'}, // 指定枚举类型 {name: 'updatedAt', cast: 'timestamp'} // 指定timestamp类型 ], {table: 'myTable'}); // 待更新数据:updatedAt直接传Date对象,无需转ISO字符串 const entries = [ { id: "someId", comparator: "gt", updatedAt: new Date() } ]; // 生成更新语句 const updateQuery = pgp.helpers.update(entries, cs) + ' WHERE v.id = t.id';
生成的SQL会自动为字段添加类型转换,示例:
update "myTable" as t set "comparator"=v."comparator"::comparator_type,"updatedAt"=v."updatedAt"::timestamp from (values('someId','gt','2023-02-17T19:46:38.723Z')) as v("id","comparator","updatedAt") WHERE v.id = t.id
方法2:直接传递Date对象(针对timestamp字段)
pg-promise支持直接传递Date对象,会自动将其转换为PostgreSQL可识别的timestamp格式,无需手动调用toISOString(),结合方法1使用效果最优。
方法3:手动添加类型转换(不推荐)
若不想使用ColumnSet,可手动在生成的SQL中为字段添加类型转换,但这种方式灵活性差:
update "myTable" as t set "comparator"=v."comparator"::comparator_type,"updatedAt"=v."updatedAt"::timestamp from (values('someId','gt','2023-02-17T19:46:38.723Z')) as v("id","comparator","updatedAt") WHERE v.id = t.id
验证效果
执行修改后的更新语句,PostgreSQL会正确识别enum和timestamp类型,不再抛出类型不匹配的错误。
内容的提问来源于stack exchange,提问作者Ninja-aman
相关产品推荐
相关产品推荐

