首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Sequelize insert no erro on duplicated

Sequelize insert no erro on duplicated
EN

Stack Overflow用户
提问于 2019-06-27 21:41:03
回答 1查看 150关注 0票数 0

写这段代码是为了理解M:N关系。想法很简单,PK是由其他表中的2个FK组成的。

检查MySQL表是正常的,约束是正常的,唯一的问题是,关系的重复的Add on PK没有包括在内(按预期工作),但也没有抛出错误。

代码如下:

代码语言:javascript
复制
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!');
});

正如你所看到的,我用一个有效的和一个无效的强制添加了另一个,有效的一个被插入,复制一个被忽略。为什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-28 11:58:00

我认为如果你分析生成的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)

因此,如果您想禁止具有相同密钥的项,那么您应该在您的foreign key上设置unique constraint

下面是来自sequelize manual的示例代码。

代码语言:javascript
复制
 // 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' },

在你的例子中,它看起来像这样,

代码语言:javascript
复制
tag_id: {
 type: DataTypes.INTEGER,
 references: {
   model: 'Post',
   key: 'id',
 },
 unique: 'constraint name'
}

因为您正在对tag_id设置唯一约束。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56792378

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档