创建或更新Sequelize

Thi*_*ira 36 mysql node.js sequelize.js

我在我的Nodejs项目中使用Sequelize,我发现了一个问题,我很难解决.基本上我有一个cron从服务器获取一个对象数组,而不是将它作为对象插入我的数据库(对于这种情况,卡通).但如果我已经拥有其中一个对象,我必须更新它.

基本上我有一个对象数组,可以使用BulkCreate()方法.但是当Cron再次启动时,它并没有解决它,因此我需要使用upsert true标志进行某种更新.主要问题:我必须有一个回调,在所有这些创建或更新之后只触发一次.有谁知道我该怎么做?迭代一个对象数组..创建或更新它然后获得一个回调?

感谢您的关注

tsu*_*suz 51

文档中,where一旦有了对象,就不需要查询来执行更新.此外,使用promise应简化回调:

履行

function upsert(values, condition) {
    return Model
        .findOne({ where: condition })
        .then(function(obj) {
            // update
            if(obj)
                return obj.update(values);
            // insert
            return Model.create(values);
        })
}
Run Code Online (Sandbox Code Playgroud)

用法

upsert({ first_name: 'Taku' }, { id: 1234 }).then(function(result){
    res.status(200).send({success: true});
});
Run Code Online (Sandbox Code Playgroud)

注意

  1. 这个操作不是原子的
  2. 创建2个网络呼叫

这意味着建议重新考虑这种方法,并且可能只是在一次网络呼叫中更新值,并且:

  1. 查看返回的值(即rows_affected)并决定要做什么
  2. 如果更新操作成功,则返回成功.这是因为资源是否存在不在此服务的责任范围内.


Alv*_*oao 14

你可以使用upsert 方式更容易.

实施细节:

MySQL - 作为单个查询实现INSERT值ON DUPLICATE KEY
UPDATE值PostgreSQL - 作为具有异常处理的临时函数实现:INSERT EXCEPTION WHEN unique_constraint UPDATE
SQLite -实现为两个查询INSERT; UPDATE.这意味着无论行是否已存在,都会执行更新

  • @IanGrainger-不再了!/sf/answers/3521099151/ (2认同)
  • 该链接已损坏“upsert”的当前 API 文档:https://sequelize.org/api/v6/class/src/model.js~model#static-method-upsert (2认同)

Sim*_*kir 11

我喜欢Ataik的想法,但是它缩短了一点:

async function updateOrCreate (model, where, newItem) {
    // First try to find the record
   const foundItem = await model.findOne({where});
   if (!foundItem) {
        // Item not found, create a new one
        const item = await model.create(newItem)
        return  {item, created: true};
    }
    // Found an item, update it
    const item = await model.update(newItem, {where});
    return {item, created: false};
}
Run Code Online (Sandbox Code Playgroud)

用法:

function updateOrCreate (model, where, newItem) {
    // First try to find the record
    return model
    .findOne({where: where})
    .then(function (foundItem) {
        if (!foundItem) {
            // Item not found, create a new one
            return model
                .create(newItem)
                .then(function (item) { return  {item: item, created: true}; })
        }
         // Found an item, update it
        return model
            .update(newItem, {where: where})
            .then(function (item) { return {item: item, created: false} }) ;
    }
}
Run Code Online (Sandbox Code Playgroud)

可选:在这里添加错误处理,但我强烈建议链接一个请求的所有promise,并在最后有一个错误处理程序.

updateOrCreate(models.NewsItem, {slug: 'sometitle1'}, {title: 'Hello World'})
    .then(function(result) {
        result.item;  // the model
        result.created; // bool, if a new item was created.
    });
Run Code Online (Sandbox Code Playgroud)


Ate*_*eik 9

这可能是个老问题,但这就是我所做的:

var updateOrCreate = function (model, where, newItem, onCreate, onUpdate, onError) {
    // First try to find the record
    model.findOne({where: where}).then(function (foundItem) {
        if (!foundItem) {
            // Item not found, create a new one
            model.create(newItem)
                .then(onCreate)
                .catch(onError);
        } else {
            // Found an item, update it
            model.update(newItem, {where: where})
                .then(onUpdate)
                .catch(onError);
            ;
        }
    }).catch(onError);
}
updateOrCreate(
    models.NewsItem, {title: 'sometitle1'}, {title: 'sometitle'},
    function () {
        console.log('created');
    },
    function () {
        console.log('updated');
    },
    console.log);
Run Code Online (Sandbox Code Playgroud)

  • 提示:使用promise链接进行错误处理并节省50%的代码:) (3认同)

Nik*_*nyy 7

User.upsert({ a: 'a', b: 'b', username: 'john' })
Run Code Online (Sandbox Code Playgroud)

它将尝试通过第一个参数中的哈希查找记录以更新它,如果找不到它 - 那么将创建新记录

是续集测试中的使用示例

it('works with upsert on id', function() {
    return this.User.upsert({ id: 42, username: 'john' }).then(created => {
        if (dialect === 'sqlite') {
            expect(created).to.be.undefined;
        } else {
            expect(created).to.be.ok;
        }

        this.clock.tick(1000);
        return this.User.upsert({ id: 42, username: 'doe' });
    }).then(created => {
        if (dialect === 'sqlite') {
            expect(created).to.be.undefined;
        } else {
            expect(created).not.to.be.ok;
        }

        return this.User.findByPk(42);
    }).then(user => {
        expect(user.createdAt).to.be.ok;
        expect(user.username).to.equal('doe');
        expect(user.updatedAt).to.be.afterTime(user.createdAt);
    });
});

Run Code Online (Sandbox Code Playgroud)