Prismaで参照先のレコード削除にハマった話
バックエンドおはこんにちばんは。最近は Node.js / TypeScript で使用出来る ORM のPrismaを触っています。
そこでハマった、一対多 や 多対多 のようなリレーションをしているテーブルのレコードの削除について、どのような対応したのかを紹介しようと思います。
実行環境
- Prisma 2.14.0
事象内容
リレーションしているテーブルのレコードに対して、Prisma のDeleteを使うと以下のエラーが発生しました。
The change you are trying to make would violate the required relation 'XXXX' between the 'XXXX' and 'XXXX' models.
あれ?何か設定漏れてたかなっと思い色々調べた結果、カスケードの削除(参照先が無くなると同時に削除される)が非対応のようでした...
一応、ロードマップ上では対応するよう進んでいるようです。優先度高くないっぽいけど。
更に調べてみると、Pal.js を使うと対応できるよっというコメントがあったので実際に試してみました。
packageを追加
Pal.js を追加していきます。(何故かgraphql入れないと動かんかった。闇)
yarn add paljs/plugins graphql
事前設定
参照先のレコードをどう扱うか設定していきます。以下の二つが設定可能です。
SET_NULL
:関連するレコードをにnull
に設定します。CASCADE
:関連するレコードを削除します。
/// @onDelete(CASCADE)
のように設定します。以下は適当な例です。
schema.prisma
model User {
id Int @id @default(autoincrement())
/// @onDelete(CASCADE)
userDetail UserDetail?
}
model UserDetail {
id Int @id @default(autoincrement())
user User @relation(fields: [userId], references: [id])
userId Int
displayName String
}
削除処理
以下のようにPal.js のDelete処理を行えば、リレーションをしているテーブルのレコードも含めて削除できます。
export const deleteUser = async (id: User['id']) => {
const prismaDelete = new PrismaDelete(prisma)
return await prismaDelete.onDelete({
model: 'User',
where: { id },
deleteParent: true
})
}
最後に
暫定対応をご紹介しましたが、Prisma が対応してくれると良いですね。同じようにハマった人の参考になれば幸いです。