Bagaimana cara memperbarui catatan menggunakan sequelize for node?

117

Saya membuat RESTful API dengan NodeJS, express, express-resource, dan Sequelize yang digunakan untuk mengelola set data yang disimpan dalam database MySQL.

Saya mencoba mencari cara untuk mengupdate record dengan benar menggunakan Sequelize.

Saya membuat model:

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

Kemudian, di pengontrol sumber daya saya, saya menetapkan tindakan pembaruan.

Di sini saya ingin dapat memperbarui catatan di mana id cocok dengan req.paramsvariabel.

Pertama saya membangun model dan kemudian saya menggunakan updateAttributesmetode untuk memperbarui catatan.

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

Sekarang, ini tidak benar-benar menghasilkan kueri pembaruan seperti yang saya harapkan.

Sebagai gantinya, kueri sisipkan dijalankan:

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

Jadi pertanyaan saya adalah: Apa cara yang tepat untuk mengupdate record menggunakan Sequelize ORM?

a_arias
sumber

Jawaban:

110

Saya belum pernah menggunakan Sequelize , tetapi setelah membaca dokumentasinya, terlihat jelas bahwa Anda sedang membuat instance objek baru , itulah mengapa Sequelize menyisipkan record baru ke dalam db.

Pertama, Anda perlu mencari record itu, mengambilnya dan baru setelah itu mengubah propertinya dan memperbaruinya , misalnya:

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 () {})
    }
  })
alessioalex.dll
sumber
Ini berfungsi, namun saya harus mengubahnya .successke.then
Adam F
1
Haruskah demikian Project.findOne(?
JBaczuk
2
Pertanyaan lama tapi relevan jika mencari hari ini (seperti yang saya lakukan). Pada Sequelize 5, cara yang benar untuk menemukan record adalah dengan findByPk(req.params.id)mengembalikan sebuah instance.
cstrutton
2
Ini seharusnya tidak direkomendasikan, ini mengirimkan 2 kueri yang dapat dilakukan dengan satu kueri. Silakan periksa jawaban lain di bawah ini.
Tᴀʀᴇǫ Mᴀʜᴍᴏᴏᴅ
219

Sejak versi 2.0.0 Anda perlu membungkus klausa where Anda di whereproperti:

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

Perbarui 2016-03-09

Versi terbaru sebenarnya tidak menggunakan successdan errorlagi melainkan menggunakan thenjanji yang dapat digunakan.

Jadi kode atas akan terlihat seperti berikut:

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

Menggunakan 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

kubus
sumber
3
Dokumen dipindahkan ke: sequelize.readthedocs.org/en/latest/api/model/…
topher
Anda memiliki lebih banyak suara positif daripada jawaban utas pertama, saya pikir itu harus dipindahkan ke jawaban pertama utas jawaban ini. Bersulang.
aananddham
37

Sejak sequelize v1.7.0 Anda sekarang dapat memanggil metode update () pada model. Jauh lebih bersih

Sebagai contoh:

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

 });
Tanah pertanian
sumber
apakah ini akan menjalankan validasi juga?
Marconi
Dari apa yang saya baca di dokumen API ini adalah metode yang lebih disukai.
Michael J. Calkins
4
Ini sebenarnya sudah usang. Lihat Referensi API resmi untuk Model .
Domi
Berikut adalah dokumen-dokumen pada saat komentar ini — mereka telah pindah ke ReadTheDocs.
Chris Krycho
1
Seperti disebutkan, notasi ini tidak digunakan lagi sejak 2.0.0. Silakan lihat juga jawaban ini: stackoverflow.com/a/26303473/831499
Matthias Dietrich
22

Dan untuk orang yang mencari jawaban pada Desember 2018, ini adalah sintaks yang benar menggunakan promise:

Project.update(
    // Values to update
    {
        title:  'a very different title now'
    },
    { // Clause
        where: 
        {
            id: 1
        }
    }
).then(count => {
    console.log('Rows updated ' + count);
});
DonkeyKong
sumber
2
Ini harus menjadi jawaban teratas.
decoder7283
Tidak berfungsi pada tahun 2019: Kesalahan penolakan tidak tertangani: Nilai tidak valid [Fungsi]
salju
13

Jawaban Januari 2020
Hal yang perlu dipahami adalah bahwa ada metode pembaruan untuk Model dan metode pembaruan terpisah untuk sebuah Mesin Virtual (catatan). Model.update()memperbarui SEMUA rekaman yang cocok dan mengembalikan array, lihat Mengurutkan dokumentasi . Instance.update()memperbarui catatan dan mengembalikan objek instance.

Jadi untuk memperbarui satu catatan per pertanyaan, kodenya akan terlihat seperti ini:

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: '[email protected]',
    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)
})

Jadi, gunakan Model.findOne()atau Model.findByPkId()untuk menangani satu Instance (record) dan kemudian gunakanInstance.update()

LaughingBubba
sumber
12

Saya pikir menggunakan UPDATE ... WHEREseperti yang dijelaskan di sini dan di sini adalah pendekatan lean

Project.update(
      { title: 'a very different title no' } /* set attributes' value */, 
      { where: { _id : 1 }} /* where criteria */
).then(function(affectedRows) {
Project.findAll().then(function(Projects) {
     console.log(Projects) 
})
Hasan A Yousef
sumber
1
Ini akan menjadi jawaban yang diterima. Dengan cara ini Anda hanya dapat mengatur beberapa bidang, dan Anda dapat menentukan kriteria. Terima kasih banyak :)
Luis Cabrera Benito
5

Solusi ini tidak digunakan lagi

kegagalan | gagal | error () tidak digunakan lagi dan akan dihapus di 2.1, gunakan gaya promise sebagai gantinya.

jadi Anda harus menggunakan

Project.update(

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

    // Where clause / criteria 
    {
        _id: 1
    }

).then(function() {

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

}).catch(function(e) {
    console.log("Project update failed !");
})

Dan Anda dapat menggunakan .complete()juga

Salam

hussam
sumber
2

Menggunakan async dan menunggu di javascript Es6 modern

const title = "title goes here";
const id = 1;

    try{
    const result = await Project.update(
          { title },
          { where: { id } }
        )
    }.catch(err => console.log(err));

Anda dapat mengembalikan hasil ...

Frank HN
sumber
1

Anda bisa menggunakan metode Model.update ().

Dengan async / await:

try{
  const result = await Project.update(
    { title: "Updated Title" }, //what going to be updated
    { where: { id: 1 }} // where clause
  )  
} catch (error) {
  // error handling
}

Dengan .then (). Catch ():

Project.update(
    { title: "Updated Title" }, //what going to be updated
    { where: { id: 1 }} // where clause
)
.then(result => {
  // code with result
})
.catch(error => {
  // error handling
})
Leandro Lima
sumber
1

hai untuk memperbarui catatan itu sangat sederhana

  1. sequelize temukan catatan dengan ID (atau dengan apa yang Anda inginkan)
  2. lalu Anda lulus params dengan result.feild = updatedField
  3. jika record tidak ada di database sequelize buat record baru dengan params
  4. lihat contoh untuk lebih memahami kode # 1 menguji kode itu untuk semua versi di bawah V4
const sequelizeModel = require("../models/sequelizeModel");
    const id = req.params.id;
            sequelizeModel.findAll(id)
            .then((result)=>{
                result.name = updatedName;
                result.lastname = updatedLastname;
                result.price = updatedPrice;
                result.tele = updatedTele;
                return result.save()
            })
            .then((result)=>{
                    console.log("the data was Updated");
                })
            .catch((err)=>{
                console.log("Error : ",err)
            });

Kode untuk V5

const id = req.params.id;
            const name = req.body.name;
            const lastname = req.body.lastname;
            const tele = req.body.tele;
            const price = req.body.price;
    StudentWork.update(
        {
            name        : name,
            lastname    : lastname,
            tele        : tele,
            price       : price
        },
        {returning: true, where: {id: id} }
      )
            .then((result)=>{
                console.log("data was Updated");
                res.redirect('/');
            })
    .catch((err)=>{
        console.log("Error : ",err)
    });
bahri noredine
sumber
0

Ada dua cara Anda dapat memperbarui rekaman secara sekuel.

Pertama, jika Anda memiliki pengenal unik maka Anda dapat menggunakan klausa where atau jika Anda ingin memperbarui beberapa rekaman dengan pengenal yang sama.

Anda dapat membuat seluruh objek untuk diperbarui atau kolom tertentu

const objectToUpdate = {
title: 'Hello World',
description: 'Hello World'
}

models.Locale.update(objectToUpdate, { where: { id: 2}})

Hanya Perbarui kolom tertentu

models.Locale.update({ title: 'Hello World'}, { where: { id: 2}})

Kedua, Anda dapat menggunakan find a query untuk menemukannya dan menggunakan fungsi set and save untuk memperbarui DB.


const objectToUpdate = {
title: 'Hello World',
description: 'Hello World'
}

models.Locale.findAll({ where: { title: 'Hello World'}}).then((result) => {
   if(result){
   // Result is array because we have used findAll. We can use findOne as well if you want one row and update that.
        result[0].set(objectToUpdate);
        result[0].save(); // This is a promise
}
})

Selalu gunakan transaksi saat memperbarui atau membuat baris baru. dengan cara itu ia akan mengembalikan pembaruan apa pun jika ada kesalahan atau jika Anda melakukan beberapa pembaruan:


models.sequelize.transaction((tx) => {
    models.Locale.update(objectToUpdate, { transaction: t, where: {id: 2}});
})
Siddharth Sunchu
sumber