LoginSignup
13
5

More than 1 year has passed since last update.

Prisma で Upsert Many はないのか

Posted at

ないです。
updateMany や deleteMany はあるのに・・・
ですが似たようなことを簡単に実現できそうです。

結論

公式の例をもとにすると複数の User 情報をまとめて Upsert したい場合は以下のようになるかと思います。

 async upsertUserMany(userList: User[]):Promise<{count:number}> {

  // map関数でupsertのクエリを複数作成
  const query = userList.map(user => (
      prisma.user.upsert({
        where: {
            email: user.email,
        },
        update: {
            name: user.name,
        },
        create: {
            email: user.email,
            name: user.name,
        },
      })
  ))
  // $transaction APIで同一トランザクションで実行
  const result = await prisma.$transaction([...query])

  return { count : result.length }
}

ちょっと解説

User[]型の userList に対し map で複数回の操作を実行し、prismaPromise の query を複数生成します。この時点ではまだ DB に対し更新処理がかかりません。

$transaction で同一トランザクションで複数の upsert を実行、ここでテーブルにたいして操作が行われます。

なおreturn {count : result.length} としているのは公式のupdateManydeleteMany関数の戻り値に似せた作りをしたかっただけです。
実行されたクエリのぶんだけ返却値の要素がありますので、lengthで擬似的に操作したレコードのcountをとることができます。

$transaction はどういう挙動をとるのか?

$transactionで更新クエリがデータベースの同一トランザクション内で実行されます。
アプリケーションが関数の最後に到達すると、トランザクションはデータベースへコミットされます。
仮に処理の途中でエラーが起きると例外ををスローするので、自動的にロールバックがかかります。

参考文献

Transactions and batch queries

Prisma Client API reference

13
5
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
13
5