Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create or Update Sequelize

I'm using Sequelize in my Nodejs project and I found a problem that I'm having a hard time to solve. Basically I have a cron that gets an array of objects from a server than inserts it on my database as a object ( for this case, cartoons ). But if I already have one of the objects, I have to update it.

Basically I have a array of objects and a could use the BulkCreate() method. But as the Cron starts again, it doesn't solve it so I was needing some sort of update with an upsert true flag. And the main issue: I must have a callback that fires just once after all these creates or updates. Does anyone have an idea of how can I do that? Iterate over an array of object.. creating or updating it and then getting a single callback after?

Thanks for the attention

like image 606
Thiago Miranda de Oliveira Avatar asked Aug 18 '13 23:08

Thiago Miranda de Oliveira


People also ask

How do I use update in Sequelize?

The Model. upsert() method is a new method added in Sequelize v6 that allows you to perform an update statement only when a row with matching values already exist. To update a row, you need to specify the primary key of the row, which is the id column in case of the Users table.

What does upsert do in Sequelize?

The upsert() method accepts an object of data with the property keys serving as the column names and the property values as the column values. The method would then return an array of two elements: The instance the Model where you call the method, returning the new/updated row.

How do you create a Sequelized model?

Sequelize set up Install Sequelize database driver for the database you would like to use by running one of the commands below. Install npm package Sequelize-CLI. Create a project folder. In your project folder path, run the command below to initialize Sequelize in the folder.


2 Answers

From the docs, you don't need to query where to perform the update once you have the object. Also, the use of promise should simplify callbacks:

Implementation

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

Usage

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

Note

  1. This operation is not atomic.
  2. Creates 2 network calls.

which means it is advisable to re-think the approach and probably just update values in one network call and either:

  1. Look at the value returned (i.e. rows_affected) and decide what to do.
  2. Return success if update operation succeeds. This is because whether the resource exists is not within this service's responsibility.
like image 172
Taku Avatar answered Sep 28 '22 00:09

Taku


You can use upsert It's way easier.

Implementation details:

  • MySQL - Implemented as a single query INSERT values ON DUPLICATE KEY UPDATE values
  • PostgreSQL - Implemented as a temporary function with exception handling: INSERT EXCEPTION WHEN unique_constraint UPDATE
  • SQLite - Implemented as two queries INSERT; UPDATE. This means that the update is executed regardless of whether the row already existed or not
  • MSSQL - Implemented as a single query using MERGE and WHEN (NOT) MATCHED THEN Note that SQLite returns undefined for created, no matter if the row was created or updated. This is because SQLite always runs INSERT OR IGNORE + UPDATE, in a single query, so there is no way to know whether the row was inserted or not.
like image 34
Alvaro Joao Avatar answered Sep 28 '22 00:09

Alvaro Joao