Sequelize upsert
Мне нужно получить идентификатор для вставленной/обновленной записи при использовании .upsert()
в sequelize.
прямо сейчас .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?
});
Ответы
Ответ 1
Я не думаю, что возвращение записанной записи было доступно, когда ОП задал этот вопрос, но с тех пор это было реализовано с помощью этого PR. Начиная с Sequelize v4.32.1, вы можете передать логическое значение, returning
в качестве параметра запроса, для выбора между возвратом массива с записью и логическим значением, или просто логическое значение, указывающее, была ли создана новая запись.
Вам все еще нужно указать идентификатор записи, которую вы хотите удалить, или будет создана новая запись.
Например:
const [record, created] = await Model.upsert(
{ id: 1, name: 'foo' }, // Record to upsert
{ returning: true } // Return upserted record
);
Ответ 2
Я хотел, чтобы 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();
});
};
Использование при попытке создать/обновить ход в игре (надуманный пример alert!):
models.Game
.findOne({where: {gameId: gameId}})
.then(function(game) {
return db.Move.findCreateUpdate(
{gameId: gameId, moveNum: game.moveNum+1},
{startPos: 'kr4', endPos: 'Kp2'}
);
});
Ответ 3
Это то, что сработало для меня:
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, чтобы найти на основе вашего первичного ключа. Если он найдет то, он обновит данные, иначе он создаст новую строку/вставку в новую строку.
Ответ 4
Я знаю, что это старый пост, но в случае, если это поможет кому-либо
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)
}
}
Ответ 5
janmeier сказал:
Это поддерживается только postgres, поэтому для обеспечения соответствия API по диалектам это невозможно.
см. ниже: https://github.com/sequelize/sequelize/issues/3354
Ответ 6
Я сам решил следующее:
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
});