Tan*_*onk 4 node.js sequelize.js
我正在创建有关歌曲和艺术家的应用程序,以下是数据库架构:
歌曲有很多艺术家,而艺术家有很多歌曲,这是多对多的关系,所以我定义了一个联接表SongArtist:
SongArtist模型:
module.exports = function(sequelize, DataTypes) {
var SongArtist = sequelize.define('SongArtist', {
id: {
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true,
autoIncrement: true
},
songId: {
type: DataTypes.INTEGER,
allowNull: false,
},
artistId: {
type: DataTypes.INTEGER,
allowNull: false,
}
}, {
tableName: 'SongArtist',
});
return SongArtist;
};
Run Code Online (Sandbox Code Playgroud)
默认行为是SongArtist使用查询Songs和Artists主键('id')进行查询,但是我想使用neteaseId“歌曲和艺术家”中的列进行多对多查询,因此我otherKey在以下方法中使用:
歌曲型号:
module.exports = function(sequelize, DataTypes) {
var Songs = sequelize.define('Songs', {
id: {
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true,
autoIncrement: true
},
name: {
type: DataTypes.STRING,
allowNull: true
},
neteaseId: {
type: DataTypes.INTEGER,
allowNull: false,
unque: true
}
}, {
tableName: 'Songs',
classMethods: {
associate: (models) => {
Songs.belongsToMany(models.Artists,{
through: 'SongArtist',
foreignKey: 'songId',
otherKey: 'neteaseId'
})
}
}
});
return Songs;
};
Run Code Online (Sandbox Code Playgroud)
艺术家模型:
module.exports = function(sequelize, DataTypes) {
var Artists = sequelize.define('Artists', {
id: {
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true,
autoIncrement: true
},
name: {
type: DataTypes.STRING,
allowNull: true
},
neteaseId: {
type: DataTypes.INTEGER,
allowNull: false,
unque: true
}
}, {
tableName: 'Artists',
classMethods: {
associate: (models) => {
Artists.belongsToMany(models.Songs,{
through: 'SongArtist',
foreignKey: 'artistId',
otherKey: 'neteaseId'
})
}
}
});
return Artists;
};
Run Code Online (Sandbox Code Playgroud)
但是,当我使用以下代码执行查询时,会向我抛出错误:
models.Songs.findAll({include: [models.Artists, models.Album]})
> SequelizeDatabaseError: column Artists.SongArtist.neteaseId does not exist
Run Code Online (Sandbox Code Playgroud)
因此,如何在多对多查询中更改默认查询列,并应生成以下sql:
LEFT OUTER JOIN ("SongArtist" AS "Artists.SongArtist"
INNER JOIN "Artists" AS "Artists" ON "Artists"."neteaseId" = "Artists.SongArtist"."artistId")
ON "Songs"."id" = "Artists.songId"."songId"
Run Code Online (Sandbox Code Playgroud)
代替
LEFT OUTER JOIN ("SongArtist" AS "Artists.SongArtist"
INNER JOIN "Artists" AS "Artists" ON "Artists"."id" = "Artists.SongArtist"."artistId")
ON "Songs"."id" = "Artists.SongArtist"."songId"
Run Code Online (Sandbox Code Playgroud)
otherKey您使用的选项不是用于选择关联中使用的源模型的字段。根据文档otherKey
联接表中的外键名称(代表目标模型)或代表另一列的类型定义的对象(有关语法,请参见Sequelize.define)。使用对象时,可以添加名称属性来设置列的名称。默认为目标名称+目标主键
它在连接表中为目标模型指定外键,因此它是连接表中的列,而不是源/目标表中的列。而且,根据Sequelize的源代码,belongsToMany在这种关联中不可能使用除主键以外的其他字段。下面的代码行从源模型中选择字段
const sourceKey = this.source.rawAttributes[this.source.primaryKeyAttribute];
Run Code Online (Sandbox Code Playgroud)
哪里this.source是你的源模型,以便相当Song或Artist。如您所见,它会自动选择primaryKeyAttribute此模型的,在两种情况下均为idfield。github上甚至存在一个与您遇到的相同问题有关的问题,答案说,在这种情况下,仅主键字段是可接受的- 在belongsToMany关联中指定非主目标键
| 归档时间: |
|
| 查看次数: |
1128 次 |
| 最近记录: |