Node.js 为什么Sequelize认为我的模型没有关联?

Node.js 为什么Sequelize认为我的模型没有关联?,node.js,sequelize.js,Node.js,Sequelize.js,我试图进行Sequelize查询,但它一直告诉我我的模型没有关联。然而,我宣布一个协会。。。我想我只是没有我想的那么理解联想 我制作了一份回购协议,您可以复制该协议来亲自查看问题: 我认为我出现这个问题的原因是Sequelize不支持复合外键,所以我必须在我的联接中使用一个自定义的on子句,但它不能像预期的那样工作,因为我不能在关联中指定相同的联接方法。这就解释了为什么Sequelize有时会打印出功能完善的SQL,但查询仍然失败(可能是因为尽管数据库查询成功,但将结果转换为Sequelize

我试图进行Sequelize查询,但它一直告诉我我的模型没有关联。然而,我宣布一个协会。。。我想我只是没有我想的那么理解联想

我制作了一份回购协议,您可以复制该协议来亲自查看问题:

我认为我出现这个问题的原因是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',
});