j'ai besoin d'obtenir l'identifiant de l'enregistrement inséré/mis à jour lors de l'utilisation de .upsert()
dans la suite.
en ce moment .upsert()
renvoie un booléen indiquant si la ligne a été créée ou mise à jour.
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?
});
Je ne pense pas que le retour de l'enregistrement renversé était disponible lorsque l'OP a posé cette question, mais il a depuis été implémenté avec ceci PR . Depuis Sequelize v4.32.1 , vous pouvez passer un booléen returning
comme paramètre de requête pour choisir entre renvoyer un tableau avec l'enregistrement et un booléen, ou simplement un booléen indiquant si un nouvel enregistrement a été créé ou non.
Vous devez toujours fournir l'ID de l'enregistrement que vous souhaitez upsert ou un nouvel enregistrement sera créé.
Par exemple:
const [record, created] = await Model.upsert(
{ id: 1, name: 'foo' }, // Record to upsert
{ returning: true } // Return upserted record
);
Je voulais qu'upsert retourne l'objet créé ou mis à jour. Ce n'est pas le cas, car seul PGSQL le prend en charge directement, apparemment.
J'ai donc créé une implémentation naïve qui - probablement d'une manière non performante, et éventuellement avec toutes sortes de conditions de concurrence, le fera:
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();
});
};
Utilisation lors de la tentative de création/mise à jour d'un coup dans un jeu (exemple d'alerte artificielle!):
models.Game
.findOne({where: {gameId: gameId}})
.then(function(game) {
return db.Move.findCreateUpdate(
{gameId: gameId, moveNum: game.moveNum+1},
{startPos: 'kr4', endPos: 'Kp2'}
);
});
C'est ce qui a fonctionné pour moi:
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");
}
})
Il vérifiera db pour trouver en fonction de votre clé primaire. S'il trouve alors, il mettra à jour les données sinon il créera une nouvelle ligne/insérera dans une nouvelle ligne.
je sais que c'est un ancien poste, mais au cas où cela aiderait quelqu'un
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)
}
}
janmeier a déclaré:
Ceci n'est supporté que par postgres, donc pour garder l'API cohérente entre les dialectes, ce n'est pas possible.
veuillez voir: https://github.com/sequelize/sequelize/issues/3354
Je crois que ma solution est la plus à jour avec le codage le plus minimal.
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)
})
}