Как выполнить объединение трех таблиц с помощью Sequelize в NodeJS

#node.js #sequelize.js

Вопрос:

Я пытаюсь создать соединение из 3 таблиц с помощью Sequelize ORM. Код, который я разработал до сих пор, таков

 const sequelize = DB.GetDB(DB.reports);  const rptDB = rpts.initModels(sequelize);   rptDB.tblReportHeadings.hasMany(rptDB.tblReports, { foreignKey: rptDB.tblReports.id, targetKey: rptDB.tblReportHeadings.Report }) //Error points to Report on this next row  rptDB.tblReports.belongsTo(rptDB.tblReportHeadings, { foreignKey: rptDB.tblReportHeadings.Report, targetKey: rptDB.tblReports.id });   rptDB.tblReportHeadings.hasMany(rptDB.tblHeadings, { foreignKey: rptDB.tblHeadings.id, targetKey: rptDB.tblReportHeadings.Heading })  rptDB.tblHeadings.belongsTo(rptDB.tblReportHeadings, { foreignKey: rptDB.tblReportHeadings.Heading, targetKey: rptDB.tblHeadings.id });   rptDB.tblAccess.hasMany(rptDB.tblHeadings, { foreignKey: Heading, targetKey: id });  rptDB.tblHeadings.belongsTo(rptDB.tblAccess, { foreignKey: id, targetKey: Heading })   let ret = tblReports.findAll({  attributes: [  id, reportTitle  ],  include: [{  model: rptDB.tblHeadings,  attributes: [Heading]  },  {  model: rptDB.tblAccess,  where: { accessLevel: roles }  }  ],  logging: (sql) =gt; console.log(sql)  });  

но я продолжаю получать сообщение об ошибке «Отчет не определен», указывающее на первое belongsTo .

Определение таблицы было создано с помощью sequelize-auto, и я проверил, что в tblReportHeadings есть поле отчета.

Вот определения 3 соответствующих таблиц:

Заголовки сообщений

 const Sequelize = require('sequelize'); module.exports = function(sequelize, DataTypes) {  return sequelize.define('tblReportHeadings', {  id: {  autoIncrement: true,  type: DataTypes.INTEGER,  allowNull: false,  primaryKey: true  },  Report: {  type: DataTypes.INTEGER,  allowNull: true  },  Heading: {  type: DataTypes.INTEGER,  allowNull: true  }  }, {  sequelize,  tableName: 'tblReportHeadings',  schema: 'dbo',  timestamps: false,  indexes: [  {  name: "PK_tblReportHeadings",  unique: true,  fields: [  { name: "id" },  ]  },  ]  }); };  

tblHeadings

 const Sequelize = require('sequelize'); module.exports = function(sequelize, DataTypes) {  return sequelize.define('tblHeadings', {  id: {  autoIncrement: true,  type: DataTypes.INTEGER,  allowNull: false,  primaryKey: true  },  Heading: {  type: DataTypes.STRING(100),  allowNull: true  }  }, {  sequelize,  tableName: 'tblHeadings',  schema: 'dbo',  timestamps: false,  indexes: [  {  name: "PK_tblHeadings",  unique: true,  fields: [  { name: "id" },  ]  },  ]  }); };  

tblAccess

 const Sequelize = require('sequelize'); module.exports = function(sequelize, DataTypes) {  return sequelize.define('tblAccess', {  id: {  autoIncrement: true,  type: DataTypes.INTEGER,  allowNull: false,  primaryKey: true  },  Heading: {  type: DataTypes.INTEGER,  allowNull: true  },  accessLevel: {  type: DataTypes.STRING(40),  allowNull: true  }  }, {  sequelize,  tableName: 'tblAccess',  schema: 'dbo',  timestamps: false,  indexes: [  {  name: "PK_tblAccess",  unique: true,  fields: [  { name: "id" },  ]  },  ]  }); };  

Я уверен, что проблема заключается в том, как я создаю соединение, но как новичок, чтобы продолжить, я не уверен, в чем заключается проблема.

Запрос, который я пытаюсь выполнить, заключается в следующем:

 `SELECT DISTINCT tblReports.id, tblReports.reportTitle, tblHeadings.Heading  FROM tblReports INNER JOIN  tblReportHeadings ON tblReports.id = tblReportHeadings.Report INNER JOIN  tblHeadings ON tblReportHeadings.Heading = tblHeadings.id INNER JOIN  tblAccess ON tblHeadings.id = tblAccess.Heading  WHERE (LOWER(tblAccess.accessLevel) IN (${roles.join(',')}))  ORDER BY tblReports.reportTitle`  

Ответ №1:

Таким образом, проблема, с которой я столкнулся, была устранена не путем изменения кода выше, а скорее кода соединения, написанного ниже:

 rptDB.tblAccess.hasMany(rptDB.tblHeadings, { foreignKey: Heading, targetKey: id });  rptDB.tblHeadings.belongsTo(rptDB.tblAccess, { foreignKey: id, targetKey: Heading })   

пришлось поменять на

 rptDB.tblAccess.hasMany(rptDB.tblHeadings, { foreignKey: rptDB.tblAccess.Heading, targetKey: rptDB.tblHeadings.id });  rptDB.tblHeadings.belongsTo(rptDB.tblAccess, { foreignKey: rptDB.tblHeadings.id, targetKey: rptDB.tblAccess.Heading })  

для того, чтобы работать.

С этим кодом все еще существует множество проблем, но это решение для этого конкретного сообщения об ошибке. По-видимому, здесь важно полностью квалифицировать каждую таблицу, и использование коротких путей, предполагающих, что Sequelize соберет фрагменты (как это иногда бывает), ненадежно.