Node JS Sequelize执行原生查询提示表不存在但表实际存在如何解决
问题根源
你使用的PostgreSQL数据库对双引号包裹的标识符大小写严格敏感,你在SQL语句中用双引号包裹了"UserTeams"表名,要求数据库严格匹配大写开头的驼峰格式表名,只要实际存储的表名大小写、命名格式和你写的不一致,就会抛出relation does not exist错误。
修复方案
按照优先顺序选择以下方案即可:
- 优先使用Sequelize模型查询,避免手动处理表名映射
Sequelize会自动按照你定义模型时的配置处理表名、字段名的映射,不需要手动写原生SQL拼接:
const { Op } = require('sequelize'); const records = await UserTeam.findOne({ attributes: ['team_id', 'user_id'], where: { userId: userId, team_id: { [Op.in]: Sequelize.literal('(SELECT "GameTeams"."team_id" FROM "GameTeams" WHERE "GameTeams"."game_id"=:gameId)') } }, replacements: { gameId: gameId } })
- 修改原生SQL的表名和实际存储保持一致
如果必须使用原生SQL,先确认数据库里的实际表名:
- 如果表名是Sequelize默认生成的下划线小写格式
user_teams,直接去掉所有双引号即可,PostgreSQL会自动把未加双引号的标识符转成小写匹配:
let sql = 'SELECT user_teams.team_id,user_teams.user_id'; sql += ' FROM user_teams'; sql += ' WHERE user_teams.user_id=:userId AND user_teams.team_id IN'; sql += ' (SELECT game_teams.team_id FROM game_teams WHERE game_teams.game_id=:gameId)'; sql += ' LIMIT 1';
- 如果表名确实是驼峰格式
UserTeams,但存放在非默认schema下,需要在表名前加上schema前缀,比如默认public schema:
let sql = 'SELECT "UserTeams"."team_id","UserTeams"."user_id"'; sql += ' FROM "public"."UserTeams"'; sql += ' WHERE "UserTeams"."user_id"=:userId AND "UserTeams"."team_id" IN'; sql += ' (SELECT "public"."GameTeams"."team_id" FROM "public"."GameTeams" WHERE "GameTeams"."game_id"=:gameId)'; sql += ' LIMIT 1';
验证方法
你可以把拼接好的SQL直接放到PostgreSQL客户端执行,如果同样报错,就可以确认是表名大小写、schema的问题,和Sequelize的调用逻辑无关。
内容的提问来源于stack exchange,提问作者Wai Yan Hein
相关产品推荐
相关产品推荐

