2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Knex.jsでMySQLのUPSERTを実行する方法

Last updated at Posted at 2020-07-06

Knex.jsで、MySQLのUPSERTを実行する方法を紹介します。

UPSERTとは

UPSERTとは、RDBにおいてキーが重複するレコードがあればUPDATEし、なければINSERTする処理のことです。
といっても、UPDATE文やINSERT文のようにUPSERT文があるわけではないので、データベース製品によってその構文は異なります。

MySQLにおけるUPSERT

MySQLでUPSERTを行なうには、INSERT ... ON DUPLICATE KEY UPDATE構文を用います。1

INSERT INTO `users` (`id`, `name`, `status`)
  VALUES (1, 'Alice', 'I\'m happy')
  ON DUPLICATE KEY UPDATE `id` = 1, `name` = 'Alice', `status` = 'I\'m happy';

UPSERT用関数を作成

Knex.js自体にはUPSERT用のAPIはないので、UPSERTを実行するための関数をつくります。

import Knex from 'knex'

interface Params {
  db: Knex,
  table: string,
  record: Record<string, any>
}

/**
 * Execute UPSERT (INSERT ... ON DUPLICATE KEY UPDATE) for MySQL
 * @see https://dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html
 */
export function upsert ({
  db,
  table,
  record
}: Params): Knex.Raw<any[]> {
  const insert = db.insert(record).into(table)
  const values = Object.entries(record)
    .map(([column, value]) => db.raw('?? = ?', [column, value]))
    .join(', ')
  return db.raw(`${insert} ON DUPLICATE KEY UPDATE ${values}`)
}

この関数は、次のように使用します。

await upsert({
  db: knex,
  table: 'users',
  record: {
    id: 1,
    name: 'Alice',
    status: "I'm happy"
  }
})

戻り値の型はKnex.Raw<any[]>なので、生成されたSQL文字列を取得することもできます。

const query = upsert({
  db: knex,
  table: 'users',
  record: {
    id: 1,
    name: 'Alice',
    status: "I'm happy"
  }
})
console.log(query.toString())
await query

上記の出力を整形(可読性のために改行を追加)すると、次のようになります。

insert into `users` (`id`, `name`, `status`)
  values (1, 'Alice', 'I\'m happy')
  ON DUPLICATE KEY UPDATE `id` = 1, `name` = 'Alice', `status` = 'I\'m happy'

参考リンク

  1. MySQL :: MySQL 8.0 Reference Manual :: 13.2.6.2 INSERT ... ON DUPLICATE KEY UPDATE Statement

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?