Sequelize迁移中如何正确拆分Schema与表以生成合法MySQL外键查询?
Sequelize迁移跨Schema外键引用的MySQL语法修复
问题描述
使用Sequelize迁移创建表时,配置外键引用另一Schema下的表,Sequelize生成的SQL会将Schema与表名合并为central.deliverables,导致MySQL报错:
ERROR: Failed to open the referenced table 'central.deliverables'
错误的SQL语句示例:
ALTER TABLE `budgets` ADD CONSTRAINT `deliverableId_fkey` FOREIGN KEY (`deliverableId`) REFERENCES `central.deliverables` (`deliverableid`) ON UPDATE CASCADE ON DELETE CASCADE;
而手动将Schema与表名拆分,写成central.deliverables时,SQL可在MySQL命令行正常执行:
ALTER TABLE `budgets` ADD CONSTRAINT `deliverableId_fkey` FOREIGN KEY (`deliverableId`) REFERENCES `central`.`deliverables` (`deliverableid`) ON UPDATE CASCADE ON DELETE CASCADE;
当前使用的createTable外键配置代码:
...}, deliverableId: { type: Sequelize.DataTypes.INTEGER, allowNull: true, references: { model: { tableName: "deliverables", schema: "central", }, key: "deliverableid", }, },
解决方案
方案1:使用Sequelize.literal手动指定带反引号的表名
直接在references的model字段中用Sequelize.literal输出正确格式的Schema+表名,强制生成带单独反引号的SQL:
deliverableId: { type: Sequelize.DataTypes.INTEGER, allowNull: true, references: { model: Sequelize.literal('`central`.`deliverables`'), key: 'deliverableid', }, onUpdate: 'CASCADE', onDelete: 'CASCADE' }
方案2:提前定义跨Schema模型并引用
如果项目中需要多次引用该跨Schema表,可先在模型文件中定义对应模型,再在迁移中直接引用模型实例:
- 定义跨Schema模型(例如
models/centralDeliverables.js):
module.exports = (sequelize, DataTypes) => { return sequelize.define('CentralDeliverables', { deliverableid: { type: DataTypes.INTEGER, primaryKey: true } // 按需添加其他字段 }, { tableName: 'deliverables', schema: 'central', timestamps: false // 若目标表无createdAt/updatedAt字段需添加此配置 }); };
- 在迁移文件中引入模型并配置外键:
const CentralDeliverables = require('../models/centralDeliverables')(sequelize, Sequelize.DataTypes); // 迁移中的createTable字段配置 deliverableId: { type: Sequelize.DataTypes.INTEGER, allowNull: true, references: { model: CentralDeliverables, key: 'deliverableid', }, onUpdate: 'CASCADE', onDelete: 'CASCADE' }
问题原因
Sequelize的MySQL方言在处理references中schema+tableName的对象配置时,未正确为Schema和表名分别添加反引号,而是直接拼接成schema.table的形式,导致MySQL将整个字符串识别为单一表名,而非Schema与表的组合。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

