Sequelize upsert

匿名 (未验证) 提交于 2019-12-03 02:51:02

问题:

i need to get the id for the inserted/updated record when using .upsert() in sequelize.

right now .upsert() returns a boolean indicating whether the row was created or updated.

return db.VenueAddress.upsert({             addressId:address.addressId,             venueId: venue.venueId,             street: address.street,             zipCode: address.zipCode,             venueAddressDeletedAt: null         }).then(function(test){             //test returned here as true or false how can i get the inserted id here so i can insert data in other tables using this new id?         });

回答1:

I wanted upsert to return the created or updated object. It doesn't because only PGSQL supports it directly, apparently.

So I created a naive implementation that will - probably in a non-performant way, and possibly with all sorts of race conditions, do that:

Sequelize.Model.prototype.findCreateUpdate = function(findWhereMap, newValuesMap) {   return this.findOrCreate({     where: findWhereMap,      defaults: findWhereMap   })   .spread(function(newObj, created) {     // set:     for(var key in newValuesMap) {       newObj[key] = newValuesMap[key];     }      return newObj.save();   }); };

Usage when trying to create/update a move in a game (contrived example alert!):

models.Game .findOne({where: {gameId: gameId}}) .then(function(game) {   return db.Move.findCreateUpdate(     {gameId: gameId, moveNum: game.moveNum+1},      {startPos: 'kr4', endPos: 'Kp2'}   ); });


回答2:

This is what worked for me:

Model.upsert({     title:your title,     desc:your description,     location:your locations }).then(function (test) {     if(test){         res.status(200);         res.send("Successfully stored");     }else{         res.status(200);         res.send("Successfully inserted");     } })

It will check db to find based on your primary key. If it finds then, it will update the data otherwise it will create a new row/insert into a new row.



回答3:

i know this is an old post, but in case this helps anyone

const upsert = async (model: any, values: any, condition: any): Promise<any> => {   const obj = await model.findOne({ where: condition })   if (obj) {     // only do update is value is different from queried object from db     for (var key in values) {       const val = values[key]       if (parseFloat(obj[key]) !== val) {         obj.isUpdatedRecord = true         return obj.update(values)       }     }     obj.isUpdatedRecord = false     return obj    } else {     // insert     const merged = { ...values, ...condition }     return model.create(merged)   } }


回答4:

janmeier said:

This is only supported by postgres, so to keep the API consistent across dialects this is not possible.

please see : https://github.com/sequelize/sequelize/issues/3354



回答5:

I don't think that returning the upserted record was available when the OP asked this question, but it has since been implemented with this PR. As of Sequelize v4.32.1, you can pass a boolean "returns" as a query param to select between returning an array with the record and a boolean or just a boolean indicating whether or not a new record was created.

You do still need to provide the id of the record you want to upsert or a new record will be created.

For example:

const [record, created] = await Model.upsert(   { id: 1, name: 'foo' }, // Record to upsert   { returning: true }     // Return upserted record );


回答6:

Which I myself resolved as follows:

return db.VenueAddress.upsert({         addressId:address.addressId,         venueId: venue.venueId,         street: address.street,         zipCode: address.zipCode,         venueAddressDeletedAt: null     },{individualHooks: true}).then(function(test){          // note individualHooks     });


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