🦾
【Prisma】upsertで冗長なコードとおさらば!レコードの存在チェック不要の便利な更新方法
はじめに
Prismaを使っていて、こんなコードを書いていませんか?
// 従来の冗長な書き方
const existingUser = await prisma.user.findUnique({
where: { email: 'example@example.com' },
});
if (existingUser) {
// 存在すれば更新
await prisma.user.update({
where: { email: 'example@example.com' },
data: { name: '山田太郎' },
});
} else {
// 存在しなければ新規作成
await prisma.user.create({
data: {
email: 'example@example.com',
name: '山田太郎',
},
});
}
私は上記の様にコードを書いていました。
しかし、実はこの処理は1行で書けます。それがupsertです!
upsertとは
upsert = update + insert の造語で、データが存在すれば更新、存在しなければ作成する操作を1つのメソッドで実現できます。
メリット
- ✅ コードがシンプルになる
- ✅ 存在チェックのクエリが不要
基本的な使い方
構文
await prisma.モデル名.upsert({
where: {
// ユニーク制約のあるフィールドで検索
},
update: {
// 存在する場合の更新内容
},
create: {
// 存在しない場合の作成内容
},
});
シンプルな例
// ユーザープロフィールの更新または作成
const user = await prisma.user.upsert({
where: {
email: 'example@example.com',
},
update: {
name: '山田太郎',
profile: '更新されたプロフィール',
},
create: {
email: 'example@example.com',
name: '山田太郎',
profile: '新規プロフィール',
},
});
console.log(user); // 更新または作成されたユーザー情報
なんとたったこれだけです
実装例
従来の書き方と、今回ご紹介したupsertを利用した書き方で比較してみます。
例1: ユーザー設定の保存
ユーザーの設定を保存する際、初回は新規作成、2回目以降は更新したい場合:
// 従来の書き方(冗長)
const setting = await prisma.userSetting.findUnique({
where: { userId: user.id },
});
if (setting) {
await prisma.userSetting.update({
where: { userId: user.id },
data: { theme: 'dark', language: 'ja' },
});
} else {
await prisma.userSetting.create({
data: {
userId: user.id,
theme: 'dark',
language: 'ja',
},
});
}
// upsertを使った書き方(シンプル)
await prisma.userSetting.upsert({
where: { userId: user.id },
update: {
theme: 'dark',
language: 'ja',
},
create: {
userId: user.id,
theme: 'dark',
language: 'ja',
},
});
例2: いいね機能
投稿へのいいね(トグル機能)を実装する場合:
// いいねを追加または削除
const like = await prisma.postLike.findUnique({
where: {
userId_postId: {
userId: user.id,
postId: post.id,
},
},
});
if (like) {
// すでにいいね済みなら削除
await prisma.postLike.delete({
where: {
userId_postId: {
userId: user.id,
postId: post.id,
},
},
});
} else {
// いいねしていなければ追加
await prisma.postLike.create({
data: {
userId: user.id,
postId: post.id,
},
});
}
// upsertでシンプルに(isActiveフラグで管理)
await prisma.postLike.upsert({
where: {
userId_postId: {
userId: user.id,
postId: post.id,
},
},
update: {
isActive: !like.isActive, // トグル
},
create: {
userId: user.id,
postId: post.id,
isActive: true,
},
});
注意点
whereにはユニーク制約が必須
upsertのwhere句には、@uniqueまたは@@unique、@idが設定されたフィールドが必要です。
まとめ
-
upsertを使えば、存在チェック→条件分岐→更新/作成の冗長なコードが不要に - パフォーマンスも向上し、コードも読みやすくなる
- ユニーク制約のあるフィールドでのみ使用可能
- 設定の保存、関連の更新、トグル機能など、様々な場面で活用できる
今まで冗長に書いていたコードを、ぜひupsertでリファクタリングしてみてください!
Discussion