У меня есть отношение «многие ко многим» с таблицей объединения в середине. Таблицами являются Cookoff, Участник и CookoffParticipant. Я должен упомянуть, что я не разрешаю Sequelize создавать или изменять мои таблицы, я просто сопоставляю свои существующие отношения. Мне нужна помощь в понимании того, какие параметры отношений говорят о том, как вызвать внешний ключ, который связывает таблицу соединений с основной таблицей.Sequelize BelongsToMany с персонализированным основным ключом таблицы соединений
Как я понимаю, Sequelize предполагает, что CookoffID и MemberantID являются составным первичным ключом на CookoffParticipant. В моей ситуации я требую, чтобы первичный ключ был столбцом идентификации. Я вызываю CookoffParticipantID и создаю уникальный индекс в паре CookoffID, PartantID в таблице CookoffParticipant.
Когда я пытаюсь получить данные cookoff и участников, запросив таблицу cookoffPanticipant, Sequelize использует неправильный ключ для выполнения соединения. Должно быть что-то простое, чего я не делаю. Ниже представлена моя структура таблицы и запрос с результатами.
самовоспламенение Таблица
var Cookoff = sequelize.define("Cookoff", {
// Table columns
CookoffID: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
Title: {
type: DataTypes.STRING,
allowNull: false
},
EventDate: {
type: DataTypes.DATE,
allowNull: false
}
}, _.extend({},
// Table settings
defaultTableSettings,
{
classMethods: {
associate: function(models) {
Cookoff.belongsToMany(models.Participant, {
through: {
model: models.CookoffParticipant
},
as: "Cookoffs",
foreignKey: "CookoffID",
otherKey: "ParticipantID"
});
}
}
}
));
Участник стол
var Participant = sequelize.define("Participant", {
// Table columns
ParticipantID: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
Name: {
type: DataTypes.STRING(100),
allowNull: false
}
}, _.extend({},
defaultTableSettings,
{
classMethods: {
associate: function(models) {
Participant.belongsToMany(models.Cookoff, {
through: {
model: models.CookoffParticipant
},
as: "Participants",
foreignKey: "ParticipantID",
otherKey: "CookoffID"
});
}
}
}
));
CookoffParticipant Таблица
var CookoffParticipant = sequelize.define("CookoffParticipant", {
CookoffParticipantID: {
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true,
autoIncrement: true
},
CookoffID: {
type: DataTypes.INTEGER,
allowNull: false,
references: {
model: cookoff,
key: "CookoffID"
}
},
ParticipantID: {
type: DataTypes.INTEGER,
allowNull: false,
references: {
model: participant,
key: "ParticipantID"
}
}
}, _.extend(
{ },
defaultTableSettings,
{
classMethods: {
associate: function (models) {
CookoffParticipant.hasOne(models.Cookoff, { foreignKey: "CookoffID" });
CookoffParticipant.hasOne(models.Participant, { foreignKey: "ParticipantID" });
}
}
}
));
Мой запрос
return cookoffParticpants.findOne({
where: { CookoffID: cookoffID, ParticipantID: participantID },
include: [
{ model: participants },
{ model: cookoffs }
]
});
Сгенерированный SQL
SELECT
[CookoffParticipant].[CookoffParticipantID],
[CookoffParticipant].[CookoffID],
[CookoffParticipant].[ParticipantID],
[Participant].[ParticipantID] AS [Participant.ParticipantID],
[Participant].[Name] AS [Participant.Name],
[Cookoff].[CookoffID] AS [Cookoff.CookoffID],
[Cookoff].[Title] AS [Cookoff.Title],
[Cookoff].[EventDate] AS [Cookoff.EventDate]
FROM [CookoffParticipant] AS [CookoffParticipant]
LEFT OUTER JOIN [Participant] AS [Participant]
ON [CookoffParticipant].[CookoffParticipantID] = [Participant].[ParticipantID] -- This should be CookoffParticipant.ParticipantID
LEFT OUTER JOIN [Cookoff] AS [Cookoff]
ON [CookoffParticipant].[CookoffParticipantID] = [Cookoff].[CookoffID] -- This should be CookoffParticipant.CookoffID
WHERE [CookoffParticipant].[CookoffID] = 1
AND [CookoffParticipant].[ParticipantID] = 6
ORDER BY [CookoffParticipantID]
OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY;
Вы можете видеть, что Sequelize пытается присоединиться CookoffParticipant.CookoffParticipantID ON Participant.ParticipantID, где он должен быть CookoffParticipant.ParticipantID = Participant.ParticipantID и аналогично для CookoffID. Что я здесь делаю неправильно?
Заранее благодарю вас за помощь.
Спасибо. Ключевая ошибка заключалась в использовании hasOne вместо applyTo. Это решение немедленно устранило проблему. – rictionaryFever