How to ignore SequelizeUniqueConstraintError in Sequelize?

有些话、适合烂在心里 提交于 2021-01-29 09:47:27

问题


Using the example from the documentation, everything works well only at the first insertion. After the second and subsequent, errors appear.

const Product = this.sequelize.define('Product', {
  title: Sequelize.STRING
});
const Tag = this.sequelize.define('Tag', {
  name: Sequelize.STRING,
  unique: true
});
const ProductTag = this.sequelize.define('ProductTag', {
  product_id: Sequelize.INTEGER,
  tag_id: Sequelize.INTEGER
});

Product.belongsToMany(Tag, {through: 'ProductTag', as: 'tag'});
Tag.belongsToMany(Product, {through: 'ProductTag'});

The first insert works fine.

Product.create({
  title: 'Chair',
  tag: [
    { name: 'Alpha'},
    { name: 'Beta'}
  ]
}, {
  include: [{
    model: Tag,
    as: 'tag'
  }]
})

SQL logs

INSERT INTO "Product" ("id","title","created_at","updated_at") VALUES (DEFAULT,'Chair','2019-02-25 12:51:50.802 +00:00','2019-02-25 12:51:50.802 +00:00') RETURNING *;
INSERT INTO "Tag" ("id","name","created_at","updated_at") VALUES (DEFAULT,'Alpha','2019-02-25 12:51:51.061 +00:00','2019-02-25 12:51:51.061 +00:00') RETURNING *;
INSERT INTO "Tag" ("id","name","created_at","updated_at") VALUES (DEFAULT,'Beta','2019-02-25 12:51:51.061 +00:00','2019-02-25 12:51:51.061 +00:00') RETURNING *;
INSERT INTO "ProductTag" ("product_id","tag_id","created_at","updated_at") VALUES (1,1,'2019-02-25 12:51:51.068 +00:00','2019-02-25 12:51:51.068 +00:00') RETURNING *;
INSERT INTO "ProductTag" ("product_id","tag_id","created_at","updated_at") VALUES (1,2,'2019-02-25 12:51:51.072 +00:00','2019-02-25 12:51:51.072 +00:00') RETURNING *;

Subsequent insertions Product.create(...) produce errors SequelizeUniqueConstraintError

Key "(name)=(Alpha)" already exists.

How to make it so that if the tag already exists, it took the ID of the existing one and ignore the error?


回答1:


My solution.

Add method updateOrCreate

Product.updateOrCreate = function (options) {
    return this.findOrCreate(options).then(res => {
        let [row, created] = res;
        if (created) return [row, created];
        return row.update(options.defaults, options.transaction)
            .then(updated => [updated, created]);
    })
};
Tag.updateOrCreate = function (options) {
    return this.findOrCreate(options).then(res => {
        let [row, created] = res;
        if (created) return [row, created];
        return row.update(options.defaults, options.transaction)
            .then(updated => [updated, created]);
    })
};

use

let data = {
    title: 'Chair',
    tag: [
        {name: 'Alpha'},
        {name: 'Beta'}
    ]
};
return sequelize.transaction().then(t => {
    return Product.updateOrCreate({
        where: {title: data.title},
        defaults: data,
        transaction: t
    }).then(res => {
        let [product] = res;
        return Promise.all(data.tag.map(tag => {
            return Tag.updateOrCreate({
                where: {name: tag.name},
                defaults: tag,
                transaction: t
            }).then(res => {
                let [tag] = res;
                return Promise.resolve(tag);
            }).catch(err => Promise.reject(err.message));
        })).then(() => {
            t.commit();
            sequelize.close();
        }).catch(err => Promise.reject(err));
    }).catch(err => {
        t.rollback();
        sequelize.close();
    });
});


来源:https://stackoverflow.com/questions/54866952/how-to-ignore-sequelizeuniqueconstrainterror-in-sequelize

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!