Node.js 为什么Sequelize认为我的模型没有关联?
我试图进行Sequelize查询,但它一直告诉我我的模型没有关联。然而,我宣布一个协会。。。我想我只是没有我想的那么理解联想 我制作了一份回购协议,您可以复制该协议来亲自查看问题: 我认为我出现这个问题的原因是Sequelize不支持复合外键,所以我必须在我的联接中使用一个自定义的Node.js 为什么Sequelize认为我的模型没有关联?,node.js,sequelize.js,Node.js,Sequelize.js,我试图进行Sequelize查询,但它一直告诉我我的模型没有关联。然而,我宣布一个协会。。。我想我只是没有我想的那么理解联想 我制作了一份回购协议,您可以复制该协议来亲自查看问题: 我认为我出现这个问题的原因是Sequelize不支持复合外键,所以我必须在我的联接中使用一个自定义的on子句,但它不能像预期的那样工作,因为我不能在关联中指定相同的联接方法。这就解释了为什么Sequelize有时会打印出功能完善的SQL,但查询仍然失败(可能是因为尽管数据库查询成功,但将结果转换为Sequelize
on
子句,但它不能像预期的那样工作,因为我不能在关联中指定相同的联接方法。这就解释了为什么Sequelize有时会打印出功能完善的SQL,但查询仍然失败(可能是因为尽管数据库查询成功,但将结果转换为Sequelize entiteis失败)
此复制工作的前一版本也复制如下:
相关型号
models.usersRoles.belongsTo(models.invitations, {
as: 'invitation',
foreignKey: 'compositePK',
});
用户角色:
邀请:
请注意,上面我将邀请
和用户角色
模型与行models.invitations.hasMany(models.usersRoles,{foreignKey:'compositePK'})相关联
查询
const path = require('path');
const glob = require('glob');
const Promise = require('bluebird');
const Sequelize = require('sequelize');
const configs = require('./test/_helpers/getConfigs');
const models = {};
const performQuery = (db) => {
const { usersRoles, invitations } = db; // eslint-disable-line max-len
const sql = {
include: {
model: invitations,
as: 'invitation',
on: {
user: Sequelize.where(
Sequelize.col('usersRoles.userUid'),
'=',
Sequelize.col('invitation.guestUid')),
propertyManager: Sequelize.where(
Sequelize.col('usersRoles.propertyManagerUid'),
'=',
Sequelize.col('invitation.propertyManagerUid')),
tenant: Sequelize.where(
Sequelize.col('usersRoles.tenantUid'),
'=',
Sequelize.col('invitation.tenantUid')),
},
},
};
return usersRoles.findAll(sql);
};
const sequelize = new Sequelize(
configs.get('DB_NAME'),
configs.get('DB_USER'),
configs.get('DB_PSSWD'),
{
dialect: configs.get('DB_TYPE'),
host: configs.get('DB_HOST'),
port: configs.get('DB_PORT'),
});
const modelsPath = path.join(__dirname, 'sequelize/models');
const globOpts = {
cwd: modelsPath,
ignore: '**/index.js',
realPath: false,
nosort: true,
nodir: true,
};
glob('**/*.js', globOpts, (err, files) => {
Promise.map(files, (file) => {
const model = sequelize.import(path.join(modelsPath, file));
models[model.name] = model;
})
.then(() => {
Object.keys(models).forEach((modelName) => {
if (models[modelName].associate) {
models[modelName].associate(models);
}
});
return performQuery(models);
})
.then((res) => {
console.log('SUCCESS', res);
}, (reason) => {
console.error('FAILED', reason);
});
});
输出
FAILED { SequelizeEagerLoadingError: invitations is not associated to usersRoles!
at Function._getIncludedAssociation (.../node_modules/sequelize/lib/model.js:573:13)
at Function._validateIncludedElement (.../node_modules/sequelize/lib/model.js:489:53)
at options.include.options.include.map.include (.../node_modules/sequelize/lib/model.js:385:37)
at Array.map (native)
at Function._validateIncludedElements (.../node_modules/sequelize/lib/model.js:381:39)
at Promise.try.then.then (.../node_modules/sequelize/lib/model.js:1525:14)
at tryCatcher (.../node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (.../node_modules/bluebird/js/release/promise.js:512:31)
at Promise._settlePromise (.../node_modules/bluebird/js/release/promise.js:569:18)
at Promise._settlePromise0 (.../node_modules/bluebird/js/release/promise.js:614:10)
at Promise._settlePromises (.../node_modules/bluebird/js/release/promise.js:693:18)
at Async._drainQueue (.../node_modules/bluebird/js/release/async.js:133:16)
at Async._drainQueues (.../node_modules/bluebird/js/release/async.js:143:10)
at Immediate.Async.drainQueues (.../node_modules/bluebird/js/release/async.js:17:14)
at runCallback (timers.js:637:20)
at tryOnImmediate (timers.js:610:5)
at processImmediate [as _immediateCallback] (timers.js:582:5) name: 'SequelizeEagerLoadingError' }
进一步尝试
我尝试将以下行添加到邀请模型:
models.usersRoles.belongsTo(models.invitations);
在本例中,Sequelize打印一些SQL,当执行时,这些SQL完全按照预期工作,但显然它没有正确执行,因为查询仍然不工作,而是说SequelizeDatabaseError:relation“usersRoles”不存在
正在执行(默认):选择“usersRoles”、“key”、“usersRoles”、“userUid”,
“usersRoles”“roleUid”“usersRoles”“oemUid”,
“usersRoles”“PropertyManagerId”“usersRoles”“doorSchedule”,
“usersRoles”“cardId”“usersRoles”“notifyBy”,
“usersRoles”“contactEmail”“usersRoles”“tenantUid”,
“usersRoles”“createdAt”“usersRoles”“compositePK”,
“usersRoles”“invitationUid”“invitation”“uid”作为“invitation.uid”,
“邀请”。“状态”为“邀请。状态”,“邀请”。“来宾ID”
作为“邀请函.来宾ID”,“邀请函”,“名字”作为
“邀请。名字”,“邀请”,“姓氏”作为
“邀请.姓氏”,“邀请”,“电子邮件”作为“邀请.电子邮件”,
“邀请”。“移动”作为“邀请.移动”,
“邀请”。“mappingGroupUid”作为“邀请。mappingGroupUid”,
“邀请”。“门时间表”作为“邀请。门时间表”,
“邀请”。“invitedByUid”作为“invitation.invitedByUid”,
“邀请”。“adminUid”作为“invitation.adminUid”,
“邀请”。“acceptedAt”作为“邀请。acceptedAt”,
“邀请”。“已拒绝”作为“邀请。已拒绝”,
“邀请”。“propertyManagerUid”作为“邀请.propertyManagerUid”,
“邀请”。“租户ID”作为“邀请。租户ID”,
“邀请”。“联系人电子邮件”作为“邀请。联系人电子邮件”,
“邀请”。“notifyBy”作为“invitation.notifyBy”,
“邀请”。“createdAt”作为“invitation.createdAt”,
“邀请”。“updatedAt”作为“usersRoles”中的“invitation.updatedAt”
作为“usersRoles”将外部加入“邀请”作为“邀请”
“usersRoles”“userUid”“邀请”“guestUid”和
usersRoles.“PropertyManagerId”=“邀请”。“PropertyManagerId”
和“用户角色”,“租户ID”=“邀请”,“租户ID”;查询失败{
SequelizeDatabaseError:关系“usersRoles”不存在
您永远不会调用
Model.associate()
方法,这样模型就不会相互关联。诀窍是关联可能需要尚未定义的模型,所以关联必须排在最后。加载模型后,循环调用Model.associate(模型)
创建关联
用户角色
定义也不包括与邀请
的关联。在Sequelize中,如果您计划从两个对象中查询关系,则必须从您要查询的一侧定义关系,或者从这两个方定义关系。由于邀请
有许多用户角色
,因此我假设用户角色s
属于一个邀请
。您在查询中将该表引用为邀请
,因此可能需要将该关联与as
属性别名
用户角色
models.usersRoles.belongsTo(models.invitations, {
as: 'invitation',
foreignKey: 'compositePK',
});
我确实调用了
associate
。我不认为这部分代码是相关的,所以我没有把它放进去。我只是编辑了我的问题,将我创建的完整测试文件包括在内,以尽量减少错误的重现。看一看。可能说明了明显但userRoles.associate()
不包括与models.investments
的关系。您必须从双方定义关联。models.usersRoles.belongsTo(models.investments,{foreignKey:'compositePK'});
。foreignKey
也很重要,我不确定如何定义compositePK
。尝试过(请参阅最新编辑)。相同的结果(关系“usersRoles”不存在
)您没有在关联中指定foreignKey
或as
属性。查看SQL输出,它试图将邀请
别名为邀请
-左外部加入“邀请”为“邀请”
models.usersRoles.belongsTo(models.invitations, {
as: 'invitation',
foreignKey: 'compositePK',
});