186 votes

Comment mettre à jour un enregistrement en utilisant sequelize for node ?

Je suis en train de créer une API RESTful avec NodeJS, express, express-resource, et Sequelize qui est utilisée pour gérer des ensembles de données stockées dans une base de données MySQL.

J'essaie de comprendre comment mettre à jour correctement un enregistrement en utilisant Sequelize.

Je crée un modèle :

module.exports = function (sequelize, DataTypes) {
  return sequelize.define('Locale', {
    id: {
      type: DataTypes.INTEGER,
      autoIncrement: true,
      primaryKey: true
    },
    locale: {
      type: DataTypes.STRING,
      allowNull: false,
      unique: true,
      validate: {
        len: 2
      }
    },
    visible: {
      type: DataTypes.BOOLEAN,
      defaultValue: 1
    }
  })
}

Ensuite, dans mon contrôleur de ressources, je définis une action de mise à jour.

Ici, je veux pouvoir mettre à jour l'enregistrement dont l'identifiant correspond à un req.params variable.

D'abord, je construis un modèle et ensuite j'utilise les updateAttributes pour mettre à jour l'enregistrement.

const Sequelize = require('sequelize')
const { dbconfig } = require('../config.js')

// Initialize database connection
const sequelize = new Sequelize(dbconfig.database, dbconfig.username, dbconfig.password)

// Locale model
const Locales = sequelize.import(__dirname + './models/Locale')

// Create schema if necessary
Locales.sync()

/**
 * PUT /locale/:id
 */

exports.update = function (req, res) {
  if (req.body.name) {
    const loc = Locales.build()

    loc.updateAttributes({
      locale: req.body.name
    })
      .on('success', id => {
        res.json({
          success: true
        }, 200)
      })
      .on('failure', error => {
        throw new Error(error)
      })
  }
  else
    throw new Error('Data not provided')
}

Maintenant, cela ne produit pas réellement une requête de mise à jour comme je m'y attendais.

Au lieu de cela, une requête d'insertion est exécutée :

INSERT INTO `Locales`(`id`, `locale`, `createdAt`, `updatedAt`, `visible`)
VALUES ('1', 'us', '2011-11-16 05:26:09', '2011-11-16 05:26:15', 1)

Ma question est donc la suivante : quelle est la bonne façon de mettre à jour un enregistrement en utilisant Sequelize ORM ?

316voto

kube Points 419

Depuis la version 2.0.0, vous devez envelopper votre fichier dans une clause where propriété :

Project.update(
  { title: 'a very different title now' },
  { where: { _id: 1 } }
)
  .success(result =>
    handleResult(result)
  )
  .error(err =>
    handleError(err)
  )

Mise à jour 2016-03-09

La dernière version n'utilise pas success y error mais utilise plutôt then -des promesses réalisables.

Le code supérieur sera donc le suivant :

Project.update(
  { title: 'a very different title now' },
  { where: { _id: 1 } }
)
  .then(result =>
    handleResult(result)
  )
  .catch(err =>
    handleError(err)
  )

Utilisation d'async/await

try {
  const result = await Project.update(
    { title: 'a very different title now' },
    { where: { _id: 1 } }
  )
  handleResult(result)
} catch (err) {
  handleError(err)
}

http://docs.sequelizejs.com/en/latest/api/model/#updatevalues-options-promisearrayaffectedcount-affectedrows

139voto

alessioalex Points 27001

Je n'ai pas utilisé Sequelize mais après avoir lu sa documentation, il est évident que vous êtes l'instanciation d'un nouvel objet C'est pourquoi Sequelize insère un nouvel enregistrement dans la base de données.

Vous devez d'abord rechercher cet enregistrement, le récupérer, puis modifier ses propriétés et son contenu. mise à jour par exemple :

Project.find({ where: { title: 'aProject' } })
  .on('success', function (project) {
    // Check if record exists in db
    if (project) {
      project.update({
        title: 'a very different title now'
      })
      .success(function () {})
    }
  })

42voto

Farm Points 635

Depuis sequelize v1.7.0, vous pouvez maintenant appeler une méthode update() sur le modèle. Beaucoup plus propre

Par exemple :

Project.update(

  // Set Attribute values 
        { title:'a very different title now' },

  // Where clause / criteria 
         { _id : 1 }     

 ).success(function() { 

     console.log("Project with id =1 updated successfully!");

 }).error(function(err) { 

     console.log("Project update failed !");
     //handle error here

 });

41voto

LaughingBubba Points 541

Janvier 2020 Réponse
Ce qu'il faut comprendre, c'est qu'il y a une méthode de mise à jour pour le modèle et une méthode de mise à jour distincte pour une instance (enregistrement). Model.update() met à jour TOUS les enregistrements correspondants et renvoie un tableau voir la documentation de Sequelize . Instance.update() met à jour l'enregistrement et renvoie un objet d'instance.

Ainsi, pour mettre à jour un seul enregistrement selon la question, le code ressemblerait à quelque chose comme ceci :

SequlizeModel.findOne({where: {id: 'some-id'}})
.then(record => {

  if (!record) {
    throw new Error('No record found')
  }

  console.log(`retrieved record ${JSON.stringify(record,null,2)}`) 

  let values = {
    registered : true,
    email: 'some@email.com',
    name: 'Joe Blogs'
  }

  record.update(values).then( updatedRecord => {
    console.log(`updated record ${JSON.stringify(updatedRecord,null,2)}`)
    // login into your DB and confirm update
  })

})
.catch((error) => {
  // do seomthing with the error
  throw new Error(error)
})

Donc, utilisez Model.findOne() o Model.findByPkId() pour obtenir la gestion d'une seule Instance (enregistrement), puis utiliser la fonction Instance.update()

32voto

donkeykong Points 33

Et pour les personnes qui cherchent une réponse en décembre 2018, voici la syntaxe correcte en utilisant les promesses :

Project.update(
    // Values to update
    {
        title:  'a very different title now'
    },
    { // Clause
        where: 
        {
            id: 1
        }
    }
).then(count => {
    console.log('Rows updated ' + count);
});

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X