序列化在重复的密钥上没有错误插入

时间:2019-06-27 13:41:03

标签: sequelize.js

制作此代码以了解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!');
});

如您所见,我强行执行了另一个添加操作,同时添加了一个有效值和一个无效值,正在插入一个有效值,重复的一个值被忽略。为什么?

1 个答案:

答案 0 :(得分:0)

我认为,如果您分析生成的for x in range(10): print('\r H M S 0 0 ' + str(x), end="\r") time.sleep(1) ,那将非常清楚。

SQL的工作是对目标数据的外键值进行.addTags操作。

因此,它只会覆盖先前的外键值。

假设您有UPDATEPost (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' } 上设置唯一约束。