Sequelize upsert

时间:2015-03-15 16:38:42

标签: node.js sequelize.js

在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?
        });

9 个答案:

答案 0 :(得分:9)

我不认为当OP提出这个问题时,返回上传的记录是可用的,但它已经用PR实现了。从 Sequelize v4.32.1 开始,您可以传递一个布尔“返回”作为查询参数,以便在返回带有记录的数组和布尔值之间进行选择,或者只是一个布尔值来指示新记录是否为创建。

您仍然需要提供您想要 upsert 的记录的ID,否则将创建新记录。

例如:

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

答案 1 :(得分:8)

我想要upsert返回创建或更新的对象。它不是因为只有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'}
  );
});

答案 2 :(得分:5)

这对我有用:

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

它将根据您的主键检查数据库以查找。如果它找到了,它将更新数据,否则它将创建一个新行/插入到新行。

答案 3 :(得分:3)

我知道这是一个老帖子,但万一这会帮助任何人

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 :(得分:2)

詹梅尔说:

这只有postgres支持,所以为了保持API在各种方言中保持一致,这是不可能的。

请参阅:https://github.com/sequelize/sequelize/issues/3354

答案 5 :(得分:2)

它不使用upsert,但是.bulkCreate有一个updateOnDuplicate参数,如果主键已经存在,它可以让您更新某些字段(而不是创建新行)。

MyModel.bulkCreate(
  newRows,
  {
    updateOnDuplicate: ["venueId", ...]
  }
)

我相信这会返回结果对象,所以我认为这可能会启用您正在寻找的功能?

答案 6 :(得分:0)

我相信我的解决方案是最新,最少的编码。

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

答案 7 :(得分:0)

我知道这是一篇旧帖子,但如果这对任何人有帮助……您可以根据 OP 数据以这种方式获取返回的 id 或任何其他值。

   var data = {
    addressId:address.addressId,
    venueId: venue.venueId,
    street: address.street,
    zipCode: address.zipCode,
    venueAddressDeletedAt: null
   }

   const result = await db.VenueAddress.upsert(data, { returning: true });
   console.log('resulttttttttttttttttt =>', result)
   
  res.status(200).json({ message: 'Your success message', data: result[0].id});

注意到我如何传递 { returning: true } 并从结果数据中获取值。

答案 8 :(得分:-1)

我自己解决的问题如下:

<?php
            // DEFINE QUERY HERE
            $query = $dbc->prepare("INSERT INTO `notes`(`user_id`,`entry`, registration_date)
                                    VALUES (1,:entry, NOW())");

            //EXCECUTE QUERY
            $query->bindValue(':entry', $_POST['entry']);
            $query->execute();
            echo '<span style="color:red;">Note Added </span>';
            $dbc = null;
        } else {
            echo '<span style="color:red;">Note was not added, insert Admin notes</span>';
        }
    }
    catch(PDOExeption $e){
        echo $e->getMessage();
    }
?>