はじめに
あるデータをupdateで更新するのと一緒に、それと関連するデータ(中間テーブルにあるデータ)も更新したい場合、どのようにPrismaを書けば良いのでしょうか?
今回は、記事に指定したタグを付け外しする、というケースを想定し、中間テーブルのデータも一緒に更新する方法を考えます。
成果物
https://github.com/kntks/blog-code/tree/main/2023/03/prisma-upsert-with-delete
バージョン
| バージョン |
---|
npm | 8.19.3 |
Prisma | 4.10.1 |
テーブルの定義
サンプルとして、以下のデータモデルとします。
中間テーブルはExplicit many-to-many relationsに書いているように明示的に中間テーブルを定義します。
PostTags中間テーブルにデータを入れます。
post, tagのデータを作成したコード
実行されるSQL
以下のようにtagIdを 2 から 4 に変更したい場合、どのようにprisma clientを使えば良いでしょうか?
さらに今回の場合は、tagId:4となるデータは作成されていません。
そのためpostの情報を更新するタイミングで、tagが存在しない場合はtagの作成 & 中間テーブルにもデータを作成する必要があります。
結論
update
メソッドの中でdeleteMany
とupsert
を使えば可能です。
ちなみにコードを実行すると、以下のようなSQLが実行されます。
Prisma Clientの型定義を読んでみると、deleteManyに書いたNOT
の箇所にはnotIn
もあるので、これを使っても実現できます。
ちなみにコードを実行すると、以下のようなSQLが実行されます。
SQLの差分
先ほど紹介したコードは以下の部分しか変わりません。
SQLを比較すると
NOTを使ったコードは、WHERE句にNOTとANDでクエリを書いているのに対して
notInを使ったコードは、WHERE句にNOT INになっていることがわかりますね。
それ以外のINSERTやDELETE文には差分がないので、deleteManyにNOT
、notIn
どちらを使っても同じ結果が得られることがわかりました。
今回使ったコードはblog-code/prisma-upsert-with-delete - GitHubにおいています。
参考