使用Sequelize原生查询PostgreSQL时,如何替换引号并成功执行SETVAL?
解决Sequelize中PostgreSQL主键序列SETVAL执行失败问题
问题场景
使用Sequelize.js执行SETVAL更新主键自增序列值时遇到报错:
初始执行代码:
await sequelize.query(`SELECT SETVAL('${idSeqence}', max(id)) FROM "${tableName}";`)
报错信息:
error: relation "my_bottemplates_id_seq" does not exist sql: `SELECT SETVAL('my_botTemplates_id_seq', max(id)) FROM "myBotTemplates";
尝试处理双引号后的第一次修改代码:
await sequelize.query(`SELECT SETVAL(trim(both '"' from '"${idSeqence}"'), max(id)) FROM "${tableName}";`)
仍报相同错误:
error: relation "my_bottemplates_id_seq" does not exist sql: `SELECT SETVAL(trim(both '"' from '"my_botTemplates_id_seq"'), max(id)) FROM "myBotTemplates";`
第二次修改代码(语法错误):
await sequelize.query(`SELECT SETVAL(replace('${idSeqence}', ", '), max(id)) FROM "${tableName}";`)
报错信息:
error: syntax error at or near "myBotTemplates" sql: `SELECT SETVAL(replace('my_botTemplates_id_seq', ", '), max(id)) FROM "myBotTemplates";`
解决方案
1. 给序列名添加双引号
PostgreSQL会将无引号的标识符自动转为小写,而你的序列是驼峰命名(myBotTemplates_id_seq),必须用双引号包裹才能正确识别。修改代码如下:
await sequelize.query(`SELECT SETVAL('"${idSeqence}"', max(id)) FROM "${tableName}";`)
生成的SQL会正确保留序列名的大小写,PostgreSQL就能找到对应的序列。
2. 使用PostgreSQL内置函数自动获取序列名(推荐)
无需手动拼写序列名,通过pg_get_serial_sequence函数自动获取指定表主键列的序列,彻底避免名称拼写或大小写问题:
await sequelize.query(`SELECT SETVAL(pg_get_serial_sequence('"${tableName}"', 'id'), max(id)) FROM "${tableName}";`)
pg_get_serial_sequence('表名', '主键列名')会直接返回对应序列的正确名称,适配大小写和自定义序列名场景。
3. 先确认序列实际名称
如果仍有问题,先执行以下SQL查询确认序列是否存在及正确名称:
SELECT relname FROM pg_class WHERE relkind = 'S' AND relname LIKE '%myBotTemplates%';
根据返回的序列名调整代码中的idSeqence值即可。
内容的提问来源于stack exchange,提问作者jadokao
相关产品推荐
相关产品推荐

