ノードのsequelizeを使用してレコードを更新する方法は?


115

MySQLデータベースに格納されているデータセットを管理するために使用されるNodeJS、express、express-resource、およびSequelizeを使用してRESTful APIを作成しています。

Sequelizeを使用してレコードを適切に更新する方法を理解しようとしています。

モデルを作成します。

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

次に、リソースコントローラーで更新アクションを定義します。

ここでは、IDがreq.params変数と一致するレコードを更新できるようにしたいと思います。

最初にモデルを作成し、次にこのupdateAttributesメソッドを使用してレコードを更新します。

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

さて、これは私が期待するように実際に更新クエリを生成しません。

代わりに、挿入クエリが実行されます。

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

だから私の質問は:Sequelize ORMを使用してレコードを更新する適切な方法は何ですか?

回答:


109

私はSequelizeを使用していませんが、そのドキュメントを読んだ後、新しいオブジェクトをインスタンス化していることは明らかです。そのため、Sequelizeは新しいレコードをdbに挿入します。

最初に、そのレコードを検索してフェッチし、その後にのみ、プロパティを変更して更新する必要があります。次に例を示します。

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

これは機能しますが、次のように変更.successする必要がありました.then
アダムF

1
それでいいのProject.findOne(
JBaczuk

2
古い質問ですが、今日検索した場合(私がしたように)は関連があります。Sequelize 5以降、レコードを検索する正しい方法findByPk(req.params.id)は、インスタンスを返す方法です。
cstrutton

2
これはお勧めできません。1つのクエリで実行できる2つのクエリが送信されます。以下のその他の回答を確認してください。
TᴀʀᴇǫMᴀʜᴍᴏᴏᴅ

219

バージョン2.0.0以降では、where句をwhereプロパティラップする必要があります。

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

更新2016-03-09

最新バージョンでは、実際に使用していませんsuccessし、errorもはや代わりに使用していますthen-able約束を。

したがって、上のコードは次のようになります。

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

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
:ドキュメントは、に移動sequelize.readthedocs.org/en/latest/api/model/...
トファー

最初のスレッドの回答よりも賛成票が多いので、これらの回答スレッドの最初の回答に移動する必要があると思います。乾杯。
aananddham

37

sequelize v1.7.0以降、モデルでupdate()メソッドを呼び出すことができるようになりました。かなりクリーナー

例えば:

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

 });

これも検証を実行しますか?
マルコーニ

私がAPIドキュメントで読んだことから、これは推奨される方法です。
Michael J. Calkins 2014年

4
実際には非推奨になっています。Modelの公式APIリファレンスをご覧ください。
ドミ2014年

このコメントの時点でのドキュメントは以下のとおりです。ReadTheDocsに移動しました。
Chris Krycho 2014

1
前述のように、この表記は2.0.0以降廃止されました。この回答も参照してください:stackoverflow.com/a/26303473/831499
Matthias Dietrich

22

そして2018年12月に答えを探している人にとって、これはpromiseを使用した正しい構文です。

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

2
これが一番の答えになるはずです。
デコーダ7283

2019年に機能しない:未処理の拒否エラー:無効な値[関数]

13

2020年1月回答
理解すべきことは、モデルの更新メソッドとインスタンス(レコード)の個別の更新メソッドがあることです。 Model.update()一致するすべてのレコードを更新して配列返します。Sequelizeのドキュメントをご覧くださいInstance.update()レコードを更新し、インスタンスオブジェクトを返します。

したがって、質問ごとに単一のレコードを更新するには、コードは次のようになります。

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

したがって、Model.findOne()またはModel.findByPkId()を使用して単一のインスタンス(レコード)のハンドルを取得してから、Instance.update()


12

ここここでUPDATE ... WHERE説明さいるように使用することは無駄のないアプローチです

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
これは受け入れられる答えになるはずです。この方法では、一部のフィールドのみを設定でき、基準を指定できます。:)
Luis Cabrera Benito

5

このソリューションは廃止されました

failure | fail | error()は非推奨であり、2.1で削除されます。代わりにpromise-styleを使用してください。

だからあなたは使用する必要があります

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

そして、あなたは使用することができます.complete()だけでなく

よろしく


2

最新のJavaScript Es6で非同期と待機を使用する

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

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

結果を返すことができます...



1

Model.update()メソッドを使用できます。

非同期/待機あり:

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

.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

こんにちは、レコードを更新するのはとても簡単です

  1. sequelizeレコードをID(または必要なもの)で検索します
  2. それからあなたはparamsを渡します result.feild = updatedField
  3. レコードがデータベースシーケンスに存在しない場合、パラメータを使用して新しいレコードを作成します
  4. V1の下ですべてのバージョンのコード#1をテストして、コードの理解を深めるために例を見てください。
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)
            });

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

sequelizeでレコードを更新する方法は2つあります。

まず、一意の識別子がある場合はwhere句を使用でき、そうでない場合は同じ識別子で複数のレコードを更新する必要があります。

更新するオブジェクト全体または特定の列を作成できます

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

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

特定の列のみを更新する

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

次に、クエリの検索を使用してそれを検索し、設定および保存機能を使用して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
}
})

新しい行を更新または作成するときは、常にトランザクションを使用してください。これにより、エラーが発生した場合、または複数の更新を行った場合に、更新がロールバックされます。


models.sequelize.transaction((tx) => {
    models.Locale.update(objectToUpdate, { transaction: t, where: {id: 2}});
})
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.