web-dev-qa-db-ja.com

アップサートの続編

sequelizeで.upsert()を使用する場合、挿入/更新されたレコードのIDを取得する必要があります。

現在.upsert()は、行が作成または更新されたかどうかを示すブール値を返します。

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?
        });
20
Hussein Al-Far

OPがこの質問をしたときに、アップサートされたレコードを返すことができるとは思いませんが、それは [〜#〜] pr [〜#〜] で実装されました。 Sequelize v4.32.1の時点で、ブール値のreturningをクエリパラメータとして渡して、レコードを含む配列を返すか、ブール値、または新しいレコードが作成されたかどうかを示すブール値。

引き続き、必要なレコードのIDを指定する必要がありますupsertまたは新しいレコードが作成されます。

例えば:

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

アップサートが作成または更新されたオブジェクトを返すようにしたかった。明らかに、PGSQLのみが直接サポートしているためではありません。

そこで、おそらく非パフォーマンス的な方法で、おそらくあらゆる種類の競合状態で、それを行う単純な実装を作成しました。

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();
  });
};

ゲーム内で動きを作成/更新しようとするときの使用法(例の警告!):

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

これは私のために働いたものです:

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");
    }
})

主キーに基づいて検索するdbをチェックします。見つかった場合、データを更新します。見つからない場合、新しい行を作成/新しい行に挿入します。

5

私はこれが古い投稿であることを知っていますが、万が一の場合に役立ちます

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)
  }
}
3
Matthew Chung

ジャンマイヤーは言った:

これはpostgresでのみサポートされているため、方言間でAPIの一貫性を保つためにこれは不可能です。

ご覧ください: https://github.com/sequelize/sequelize/issues/3354

2
Hussein Al-Far

私のソリューションは、最小限のコーディングで最新のものだと思います。

const SequelizeModel = require('sequelize/lib/model')
SequelizeModel.upsert = function() {
  return this.findOne({
    where: arguments[0].where
  }).then(obj => {
    if(obj) {
      obj.update(arguments[0].defaults)
      return
    }
    return this.create(arguments[0].defaults)
  })
}
0
indospace.io