MongoDB connector: Model discriminators / single table inheritence
See original GitHub issueProblem
A common use case is to store different shapes of a document in the same collection and use a discriminator column to tell them apart. Raw mongodb JSON example data follows:
{
"_id": "71ed6b0f-e08e-4bad-acf2-e02653aad1aa",
"body": "This is my second post.",
"type": "post",
"slug": "prisma-is-type-safe-mongodb-client",
"title": "Prisma is a type-safe MongoDB client"
}
and
{
"_id": "7aa65cb4-e4b4-4a82-a26e-549d0bb5e3a7",
"postId": "71ed6b0f-e08e-4bad-acf2-e02653aad1aa",
"type": "comment",
"comment": "Great post!"
}
And then, these two documents can be described as follows in the Prisma Schema:
model Post {
id String @id @default(uuid()) @map("_id")
type String @default("post")
slug String @unique
title String
body String
comments Comment[]
@@map("someCollection")
}
model Comment {
id String @id @default(uuid()) @map("_id")
type String @default("comment")
post Post @relation(fields: [postId], references: [id])
postId String
comment String
@@map("someCollection")
}
With this, most things work, except if you need to fetch a list of documents directly where the criteria overlaps between the variant types:
PrismaClientUnknownRequestError2 [PrismaClientUnknownRequestError]:
Invalid `prisma.post.findMany()` invocation:
Attempted to serialize scalar 'null' with incompatible type 'String'
Workaround
A work around is to add a filter to the findMany query to only return the documents matching the desired discriminator column:
await prisma.post.findMany({
where: { type: "post" },
include: {
comments: true,
},
})
Suggested solution
Add something like @discriminator
to fields and then use it’s value whenever doing lookups for a model.
model Post {
id String @id @default(uuid()) @map("_id")
type String @default("post") @discriminator
slug String @unique
title String
body String
comments Comment[]
@@map("someCollection")
}
and so calling
await prisma.post.findMany({
include: {
comments: true,
},
})
will work.
Additional context
More than one discriminator could also be very useful.
Perhaps the @discriminator
could work like this:
@discriminator("value")
and automatically include @ignore
on the field, maybe?
Issue Analytics
- State:
- Created 2 years ago
- Reactions:5
- Comments:5 (3 by maintainers)
Top GitHub Comments
Similar request to https://github.com/prisma/prisma/issues/2505
Any updates on this issue?