Sequelize:多对多表(CROSS TABLE)关联到另一个表
Posted
技术标签:
【中文标题】Sequelize:多对多表(CROSS TABLE)关联到另一个表【英文标题】:Sequelise : Many To Many table(CROSS TABLE) associated to other table 【发布时间】:2021-04-15 18:26:52 【问题描述】:这是我的图表数据库:https://i.stack.imgur.com/CGAwh.png
我用 SEQUELIZE 制作了我的数据库模型:
型号:级别
module.exports = (sequelize, DataTypes) =>
const Level = sequelize.define(
'Level',
level_id:
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
,
label:
type: DataTypes.STRING,
allowNull: false,
unique:
args: true,
msg: 'Level:Label already exist!',
,
validate:
notEmpty: msg: `Level:Label cannot be empty!` ,
notNull: msg: `Level:Label cannot be NULL!` ,
,
,
ref:
type: DataTypes.STRING,
allowNull: true,
,
description:
type: DataTypes.TEXT,
allowNull: true,
,
,
tableName: 'levels',
timestamps: false,
);
Level.associate = (models) =>
Level.belongsToMany(models.Test,
through: models.testHasLevel,
foreignKey: 'level_id',
otherKey: 'test_id',
timestamps: false,
);
;
return Level;
;
型号:测试:
module.exports = (sequelize, DataTypes) =>
const Test = sequelize.define(
'Test',
test_id:
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
,
label:
type: DataTypes.STRING,
allowNull: false,
validate:
notEmpty: msg: `Test:label cannot be empty!` ,
notNull: msg: `Test:label cannot be NULL!` ,
,
,
isInternal:
type: DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
validate:
notEmpty: msg: `Test:isInternal cannot be empty!` ,
notNull: msg: `Test:isInternal cannot be NULL!` ,
,
,
parent_id:
type: DataTypes.INTEGER,
defaultValue: null,
allowNull: true,
,
,
tableName: 'tests',
timestamps: false,
);
Test.associate = (models) =>
Test.belongsToMany(models.Level,
through: models.testHasLevel,
foreignKey: 'test_id',
otherKey: 'level_id',
timestamps: false,
);
Test.hasMany(models.Test, foreignKey: 'parent_id', as: 'children' );
;
return Test;
;
模型:测试有模型
module.exports = (sequelize, DataTypes) =>
const testHasLevel = sequelize.define(
'testHasLevel',
,
id:
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
,
tableName: 'test_has_level',
timestamps: false,
);
testHasLevel.associate = (models) =>
testHasLevel.belongsTo(models.Test,
foreignKey: 'test_id',
targetKey: 'test_id',
);
testHasLevel.belongsTo(models.Level,
foreignKey: 'level_id',
targetKey: 'level_id',
);
;
return testHasLevel;
;
我也做了会话模型:
module.exports = (sequelize, DataTypes) =>
const Session = sequelize.define(
'Session',
session_id:
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
,
institut_id:
type: DataTypes.INTEGER,
,
start:
type: DataTypes.DATE,
,
end:
type: DataTypes.DATE,
,
test_id:
type: DataTypes.INTEGER,
,
level_id:
type: DataTypes.INTEGER,
,
limitDateSubscribe:
type: DataTypes.DATE,
,
placeAvailable:
type: DataTypes.INTEGER,
,
,
tableName: 'sessions',
timestamps: false,
);
Session.associate = (models) =>
Session.hasMany(models.sessionHasUser, foreignKey: 'session_id' );
;
return Session;
;
但我不知道如何“绑定”SESSION
和 TEST_HAS_LEVEL
和 Sequelize ....
我应该改变什么?因为我知道最后一个版本的续集不允许使用“复合密钥”。
换句话说: 如何正确地将交叉表与另一表的一对多关系关联起来?
【问题讨论】:
【参考方案1】:型号:级别
module.exports = (sequelize, DataTypes) =>
const Level = sequelize.define(
"Level",
level_id:
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
,
label:
type: DataTypes.STRING,
allowNull: false,
unique:
args: true,
msg: "Level:Label already exist!",
,
validate:
notEmpty: msg: `Level:Label cannot be empty!` ,
notNull: msg: `Level:Label cannot be NULL!` ,
,
,
ref:
type: DataTypes.STRING,
allowNull: true,
,
description:
type: DataTypes.TEXT,
allowNull: true,
,
,
tableName: "levels",
timestamps: false,
);
Level.associate = (models) =>
Level.hasMany(models.testHasLevel,
foreignKey: "level_level_id",
as: "levels",
);
;
return Level;
;
模型:测试
module.exports = (sequelize, DataTypes) =>
const Test = sequelize.define(
"Test",
test_id:
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
,
label:
type: DataTypes.STRING,
allowNull: false,
validate:
notEmpty: msg: `Test:label cannot be empty!` ,
notNull: msg: `Test:label cannot be NULL!` ,
,
,
isInternal:
type: DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
validate:
notEmpty: msg: `Test:isInternal cannot be empty!` ,
notNull: msg: `Test:isInternal cannot be NULL!` ,
,
,
parent_id:
type: DataTypes.INTEGER,
defaultValue: null,
allowNull: true,
,
,
tableName: "tests",
timestamps: false,
);
Test.associate = (models) =>
Test.hasMany(models.testHasLevel,
foreignKey: "test_test_id",
as: "tests",
);
Test.hasMany(models.Test, foreignKey: "parent_id", as: "children" );
;
return Test;
;
模型:测试有水平
module.exports = (sequelize, DataTypes) =>
const testHasLevel = sequelize.define(
"testHasLevel",
id:
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
,
test_test_id:
type: DataTypes.INTEGER,
,
level_level_id:
type: DataTypes.INTEGER,
,
,
tableName: "test_has_level",
timestamps: false,
);
testHasLevel.associate = (models) =>
testHasLevel.belongsTo(models.Test,
foreignKey: "test_test_id",
as: "tests",
);
testHasLevel.belongsTo(models.Level,
foreignKey: "level_level_id",
as: "levels",
);
testHasLevel.hasMany(models.Session,
foreignKey: "test_has_level_id",
as: "test_has_level",
);
;
return testHasLevel;
;
模型:会话
module.exports = (sequelize, DataTypes) =>
const Session = sequelize.define(
"Session",
session_id:
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
,
institut_id:
type: DataTypes.INTEGER,
,
start:
type: DataTypes.DATE,
,
end:
type: DataTypes.DATE,
,
test_has_level_id:
type: DataTypes.INTEGER,
,
limitDateSubscribe:
type: DataTypes.DATE,
,
placeAvailable:
type: DataTypes.INTEGER,
,
,
tableName: "sessions",
timestamps: false,
);
Session.associate = (models) =>
Session.belongsTo(models.testHasLevel,
foreignKey: "test_has_level_id",
as: "test_has_level",
);
;
return Session;
;
【讨论】:
以上是关于Sequelize:多对多表(CROSS TABLE)关联到另一个表的主要内容,如果未能解决你的问题,请参考以下文章