Prismaで複数のレコードを bulk update したい。
Prismaのドキュメントを確認するとupdateManyがある。
しかしupdateMany APIは、複数のレコードに同じ値をいれるものであって、期待したAPIではない。
やり方としては、愚直にupdateをループ処理するしかない、
しかしループ処理は使いたくない。
悩んで調べていると、以下のように 親の更新で子を bulk update することができた。
await prisma.my_column.update({
data: {
my_child: {
update: myArray.map((item) => ({
where: { id: item.id },
data: item,
}))
}
}
});
これなら親の数だけループ処理すればいいので、クエリを発行数をだいぶ減らすことができた。
リレーションがある場合限定になるが、覚えておくとパフォーマンスチューニング時に使える。
また、update
だけではなく、create
やリレーションの付け替えを行う connect
を使ってより複雑なupdateをすることができる。
// 子の update, create, connect を同時に行うのは update でしかできないので、
// 親がない場合は事前に create しておく
await prisma.my_column.create({
data: myData,
})
// 親の update と、
// 子の update, create, connect を同時に行う
await prisma.my_column.update({
data: {
...myData,
my_child: {
connect: myArray.map(item => ({
id: item.id
})),
update: myArray.map((item) => ({
where: { id: item.id },
data: item,
})),
create: creatingMyArray.map((item) => ({
...item,
})),
}
}
});
今回はパフォーマンスが問題になっていた部分を、これによって解消することができた。