🦌

Sequelizeで複数カラムの更新とconcatを使ったデータの追加

2023/01/20に公開

概要

業務でLambdaで以下の要件の関数を満たすを実装する機会があって、情報が落ちていなかったので記事にしたいと思います。

  • Sequelizeで複数のカラムを更新
  • カラムの既存の文字列に新たに文字列を追加(Sequelizeでconcatを使う方法)

全体のコード

コード内にコメントで軽く解説しています。(説明の都合上、1ファイル内に詰め込んでいます。)
const { Sequelize, DataTypes } = require("sequelize");

// Sequelizeのインスタンスを生成
async function loadSequelize() {
  const sequelize = new Sequelize(
    process.env.DB_NAME,
    process.env.DB_USERNAME,
    process.env.DB_PASSWORD,
    {
      host: process.env.DB_HOSTNAME,
      dialect: 'mysql',
      pool: {
        max: 2,
        min: 0,
        idle: 0,
        acquire: 3000,
        evict: 3000
      }
    });

  await sequelize.authenticate();

  return sequelize;
}

// モデルを定義(テーブル情報)
// ※カラムはサンプルです
const sampleModel = (sequelize) => {
  return sequelize.define('model', {
    id: {
      type: DataTypes.BIGINT(11),
      allowNull: false,
      autoIncrement: true,
      primaryKey: true,
    },
    name: {
      type: DataTypes.STRING,
    },
    memo: {
      type: DataTypes.TEXT,
    },
  }
}

module.exports.sampleUpdate = async (event, _context, callback) => {
  ~~

  // 以下3つの変数をPOST値とする
  const id;
  const name;
  let memo;
  
  // パフォーマンスを向上させるために sequelize のインスタンスを複数回にわたって再利用します。
  if (!sequelize) {
    sequelize = await loadSequelize();
  } else {
    // 接続プールを再起動し、接続を再利用しないようにする。
    sequelize.connectionManager.initPools();

    // `getConnection()` が `close()` によって上書きされた場合、それを復元する。
    if (sequelize.connectionManager.hasOwnProperty("getConnection")) {
      delete sequelize.connectionManager.getConnection;
    }
  }

  try {
    const model = await sampleModel(sequelize)
    const updateResult = await model.update({
      // ここで複数のカラムを指定
      name: name,
      // memoカラムの既存の文字列に新たに文字列を追加
      memo: Sequelize.fn("concat", Sequelize.col("memo"), memo)
    }, {
      where: {
        id: id
      }
    })
    callback(null, {
      statusCode: 200, body: JSON.stringify({
        message: '更新に成功しました',
        data: updateResult
      }, null, 2)
    })
    return
  } catch (error) {
    console.log('更新に失敗しました : ', error)
    callback(null, { statusCode: 500, body: '更新に失敗しました' })
    return
  } finally {
    // 呼び出し中に開いているコネクションをすべて閉じる
    // 接続を閉じる前に、進行中のクエリが終了するのを待ちます。
    await sequelize.connectionManager.close();
  }
};

Sequelizeで複数のカラムを更新

const updateResult = await sampleModel.update({
  name: name,
  memo: "これはメモです。"
}, {
  where: {
    id: id
  }
})

走ったSQL

UPDATE `sample` SET `name`=nameの値,`memo`=`これはメモです。` WHERE `id` = idの値

カラムの既存の文字列に新たに文字列を追加(Sequelizeでconcatを使う方法)

Sequelizeのドキュメントによは、以下のように記載がありました。

sequelize.col を使用すると、カラムが文字列ではなくカラムとして適切に解釈されるようになります。

ここでは、Sequelize.col("memo")でメモカラムを指定しています。

const updateResult = await sampleModel.update({
  name: name,
  memo: Sequelize.fn("concat", Sequelize.col("memo"), "hoge")
}, {
  where: {
    id: id
  }
})

走ったSQL

UPDATE `sample` SET `name`=nameの値,`memo`=`元々入っていた値 + hoge` WHERE `id` = idの値

参考記事

【MySQL】テキスト用カラムに文字を追記するupdateなSQLを作ってみた
equelize: Concat fields in WHERE LIKE clause

Discussion