Làm thế nào để cập nhật một bản ghi bằng cách sử dụng phần tiếp theo cho nút?


115

Tôi đang tạo một API RESTful với NodeJS, express, express-resource và Sequelize được sử dụng để quản lý các tập dữ liệu được lưu trữ trong cơ sở dữ liệu MySQL.

Tôi đang cố gắng tìm ra cách cập nhật bản ghi đúng cách bằng cách sử dụng Sequelize.

Tôi tạo một mô hình:

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

Sau đó, trong bộ điều khiển tài nguyên của mình, tôi xác định một hành động cập nhật.

Ở đây, tôi muốn có thể cập nhật bản ghi mà id khớp với một req.paramsbiến.

Đầu tiên tôi xây dựng một mô hình và sau đó tôi sử dụng updateAttributesphương pháp để cập nhật bản ghi.

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

Bây giờ, điều này thực sự không tạo ra một truy vấn cập nhật như tôi mong đợi.

Thay vào đó, một truy vấn chèn được thực thi:

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

Vì vậy, câu hỏi của tôi là: Cách thích hợp để cập nhật một bản ghi bằng cách sử dụng Sequelize ORM là gì?

Câu trả lời:


109

Tôi chưa sử dụng Sequelize , nhưng sau khi đọc tài liệu của nó, rõ ràng là bạn đang khởi tạo một đối tượng mới , đó là lý do tại sao Sequelize chèn một bản ghi mới vào db.

Trước tiên, bạn cần tìm kiếm bản ghi đó, tìm nạp nó và chỉ sau đó thay đổi các thuộc tính của nó và cập nhật nó, ví dụ:

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

Tác phẩm này, tuy nhiên tôi đã phải thay đổi .successđể.then
Adam F

1
Có nên Project.findOne(không?
JBaczuk

2
Câu hỏi cũ nhưng có liên quan nếu tìm kiếm ngày hôm nay (như tôi đã làm). Kể từ Sequelize 5, cách chính xác để tìm bản ghi là findByPk(req.params.id)trả về một thể hiện.
cstrutton

2
Điều này không nên được khuyến khích, nó sẽ gửi 2 truy vấn mà nó có thể được thực hiện bằng một truy vấn. Vui lòng kiểm tra các câu trả lời khác bên dưới.
Tᴀʀᴇǫ Mᴀʜᴍᴏᴏᴅ

219

Kể từ phiên bản 2.0.0, bạn cần bao bọc mệnh đề where trong một thuộc wheretính:

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

Cập nhật 2016-03-09

Phiên bản mới nhất thực sự không sử dụng successerrorthay vào đó sử dụng các thenhứa hẹn có thể sử dụng .

Vì vậy, mã trên sẽ trông như sau:

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

Sử dụng 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


3
Các tài liệu được chuyển đến: sequize.readthedocs.org/en/latest/api/model/…
topher

Bạn có nhiều lượt ủng hộ hơn câu trả lời chủ đề đầu tiên, tôi nghĩ nó nên được chuyển sang câu trả lời đầu tiên của chuỗi câu trả lời này. Chúc mừng.
aananddham

37

Kể từ phiên bản tiếp theo v1.7.0 bây giờ bạn có thể gọi một phương thức update () trên mô hình. Sạch hơn nhiều

Ví dụ:

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

 });

điều này cũng sẽ chạy xác thực chứ?
Marconi

Từ những gì tôi đã đọc trong tài liệu API, đây là phương pháp ưu tiên.
Michael J. Calkins

4
Nó thực sự đã không được dùng nữa. Xem Tham chiếu API chính thức cho Mô hình .
Domi

Đây là các tài liệu tính đến thời điểm nhận xét này — chúng đã được chuyển sang ReadTheDocs.
Chris Krycho

1
Như đã đề cập, ký hiệu này không được dùng nữa kể từ 2.0.0. Vui lòng tham khảo thêm câu trả lời này: stackoverflow.com/a/26303473/831499
Matthias Dietrich

22

Và đối với những người đang tìm kiếm câu trả lời vào tháng 12 năm 2018, đây là cú pháp chính xác sử dụng các lời hứa:

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

2
Đây phải là câu trả lời hàng đầu.
decoder7283,

Không hoạt động vào năm 2019: Lỗi từ chối chưa được xử lý: Giá trị không hợp lệ [Chức năng]
snow

13

Tháng 1 năm 2020 Câu trả lời
Điều cần hiểu là có một phương pháp cập nhật cho Mô hình và một phương pháp cập nhật riêng cho một Phiên bản (bản ghi). Model.update()cập nhật TẤT CẢ các bản ghi phù hợp và trả về một mảng, hãy xem tài liệu Trình tự hóa . Instance.update()cập nhật bản ghi và trả về một đối tượng thể hiện.

Vì vậy, để cập nhật một bản ghi cho mỗi câu hỏi, mã sẽ trông giống như sau:

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

Vì vậy, hãy sử dụng Model.findOne()hoặc Model.findByPkId()để xử lý một Phiên bản duy nhất (bản ghi) và sau đó sử dụngInstance.update()


12

Tôi nghĩ rằng sử dụng UPDATE ... WHEREnhư đã giải thích ở đâyđây là một cách tiếp cận tinh gọn

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

1
Đây sẽ là câu trả lời được chấp nhận. Bằng cách này, bạn chỉ có thể đặt một số trường và bạn có thể chỉ định tiêu chí. Cảm ơn bạn rất nhiều :)
Luis Cabrera Benito

5

Giải pháp này không được dùng nữa

fail | fail | error () không được dùng nữa và sẽ bị xóa trong 2.1, thay vào đó hãy sử dụng kiểu kiểu hứa.

vì vậy bạn phải sử dụng

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

Và bạn có thể sử dụng .complete()cũng

Trân trọng


2

Sử dụng async và chờ đợi trong javascript Es6 hiện đại

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

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

bạn có thể trả về kết quả ...



1

Bạn có thể sử dụng phương thức Model.update ().

Với 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
}

Với .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
})

1

chào để cập nhật hồ sơ nó rất đơn giản

  1. phần tiếp theo tìm bản ghi theo ID (hoặc theo những gì bạn muốn)
  2. sau đó bạn vượt qua các thông số với result.feild = updatedField
  3. nếu bản ghi không kỹ thuật số trong cơ sở dữ liệu tiếp theo, hãy tạo một bản ghi mới với các tham số
  4. xem ví dụ để hiểu thêm Mã số 1 kiểm tra mã cho tất cả các phiên bản trong 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)
            });

Mã cho 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)
    });


0

Có hai cách để bạn có thể cập nhật bản ghi ở dạng tiếp theo.

Trước tiên, nếu bạn có một số nhận dạng duy nhất thì bạn có thể sử dụng mệnh đề where hoặc mệnh đề khác nếu bạn muốn cập nhật nhiều bản ghi có cùng một số nhận dạng.

Bạn có thể tạo toàn bộ đối tượng để cập nhật hoặc một cột cụ thể

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

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

Chỉ cập nhật một cột cụ thể

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

Thứ hai, bạn có thể sử dụng find một truy vấn để tìm nó và sử dụng hàm set and save để cập nhật 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
}
})

Luôn sử dụng giao dịch trong khi cập nhật hoặc tạo hàng mới. theo cách đó, nó sẽ khôi phục mọi bản cập nhật nếu có bất kỳ lỗi nào hoặc nếu bạn thực hiện nhiều bản cập nhật:


models.sequelize.transaction((tx) => {
    models.Locale.update(objectToUpdate, { transaction: t, where: {id: 2}});
})
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.