制作此代码以了解M:N关系。这个想法很简单,PK由其他表中的2个FK组成。
在MySQL表上检查是否正常,约束是否正常,唯一的问题是,不包括重复的关系添加在PK上(按预期方式工作),而且不会引发错误。
下面的代码:
const Sequelize = require('sequelize');
const Model = Sequelize.Model
const path = 'mysql://myuser:mypass@localhost:3306/dbtest';
const sequelize = new Sequelize(path, {
logging: false
});
class PostTag extends Model { }
/*
PostTag.init({
postId: {
type: Sequelize.INTEGER,
primaryKey: true,
unique: "postTagConstraint"
},
tagId: {
type: Sequelize.INTEGER,
primaryKey: true,
unique: "postTagConstraint"
}
}, { sequelize, modelName: 'post_tag' });
*/
class Post extends Model { }
Post.init({
title: Sequelize.STRING,
text: Sequelize.STRING
}, { sequelize, modelName: 'post' });
class Tag extends Model { }
Tag.init({
name: Sequelize.STRING,
status: Sequelize.STRING
}, { sequelize, modelName: 'tag' });
/*
Post.belongsToMany(Tag, {
through: {
model: PostTag
},
foreignKey: 'postId'
});
Tag.belongsToMany(Post, {
through: {
model: PostTag
},
foreignKey: 'tagId'
});
*/
Post.belongsToMany(Tag, { through : 'PostTag' });
Tag.belongsToMany(Post, { through : 'PostTag' });
async function Add() {
let tag1 = await Tag.create({ name: 'Nice', status: 'Funcional' });
let tag2 = await Tag.create({ name: 'Bad', status: 'Not working' });
//console.log(tag1.name);
//console.log(tag2.name);
let post1 = await Post.create({ title: 'A very nice post', text: 'This is post1' });
let post2 = await Post.create({ title: 'Toxic post', text: 'This is post2' });
//console.log(`${post1.title} - ${post1.text}`);
//console.log(`${post2.title} - ${post2.text}`);
await post1.addTags([tag1, tag2]);
await post2.addTags([tag2]);
let res1 = await Post.findAll({ where: { id: 1 }, include: [Tag] });
res1.forEach(p => {
console.log(`${p.title} - ${p.text}`)
p.tags.forEach(t => console.log(`${t.name} - ${t.status}`));
});
// No error being throw on duplicated
await post2.addTags([tag1, tag2]);
}
sequelize.sync({ force: true }).then(() => {
Add();
console.log('It shall be one!');
});
如您所见,我强行执行了另一个添加操作,同时添加了一个有效值和一个无效值,正在插入一个有效值,重复的一个值被忽略。为什么?
答案 0 :(得分:0)
我认为,如果您分析生成的for x in range(10):
print('\r H M S 0 0 ' + str(x), end="\r")
time.sleep(1)
,那将非常清楚。
SQL
的工作是对目标数据的外键值进行.addTags
操作。
因此,它只会覆盖先前的外键值。
假设您有UPDATE
和Post (id1)
。
如果您致电Tag (id1), Tag(id2)
,然后致电Post.addTags([tag1])
,
结果将为Post.addTags([tag1, tag2])
和Post (id1)
。
因此,如果您要禁止使用相同的键,则应在Tag (id1, post_id1), Tag(id2, post_id1)
上设置unique constraint
。
下面是sequelize manual中的示例代码。
foreign key
在您的情况下,看起来像
// Creating two objects with the same value will throw an error. The unique property can be either a
// boolean, or a string. If you provide the same string for multiple columns, they will form a
// composite unique key.
uniqueOne: { type: Sequelize.STRING, unique: 'compositeIndex' },
uniqueTwo: { type: Sequelize.INTEGER, unique: 'compositeIndex' },
因为您要在tag_id: {
type: DataTypes.INTEGER,
references: {
model: 'Post',
key: 'id',
},
unique: 'constraint name'
}
上设置唯一约束。