Feature: Add support for `is`, `isNot` relation filters
Tenrys opened this issue · comments
They seem to be missing in the currently generated GraphQL types, I'm not certain when they are and aren't available, but I think it would be nice to have the option to use them, maybe.
https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#is
I'm not sure if it would be as easy as modifying the schema generator template. For now I'll settle with some
, I may take a look myself later
Both is
and isNot
filters were removed from 1.0.0-rc.2
(see full changelog) in favour of the newest Fluent API syntax.
This (removed):
query {
listPosts(
where: {
author: { is: { username: "xxx" } }
}
) {
title
author { username }
}
}
Is equivalent to this (supported):
query {
listPosts(
where: {
author: { username: { equals: "xxx" } }
}
) {
title
author { username }
}
}
Supporting both syntaxes simultaneously could be possible using the below Schema:
input UserScalarsWhereInput {
# ...
author: String
}
input PostWhereInput {
# ...
author: UserWhereInput
is: UserScalarsWhereInput
isNot: UserScalarsWhereInput
}
However, I'm thinking it would add (unnecessary?) complexity to detect and prevent using both syntaxes simultaneously within a single query.
Unless there is a use case in which the Fluent API syntax wouldn't allow doing the same as with is
and isNot
?
I was mostly thinking about how to check whether or not a one-to-one relationship exists. I know the equivalent would be some: {}
for one-to-many.
Would you have an example query to share (if you were to do it with the Prisma Client directly)?
model Valuation {
...
estate Estate?
...
}
model Estate {
...
valuationUuid String @unique
valuation Valuation @relation(fields: [valuationUuid], references: [uuid])
...
}
const valuations = await client.valuation.findMany({
where: {
estate: {
is: null,
},
},
});
Maybe there is a better way that I don't know of.
Another way to achieve the same would be:
query {
listValuations(
where: {
estateUuid: { equals: null }
}
) {
id
}
}
In theory this should work, though I've just tested it on my local machine - and it seems the event parser is transforming null
values into undefined
.
arguments: {
where: {
estateUuid: {
equals: undefined # this should be null
}
}
}
Can you please try and let me know if you see the same issue on your end?
I think it wouldn't hurt to bring back <Model>RelationFilter
as it is in Prisma, with the same definition as <Model>WhereInput
, except with those two deleted lines brought back:
12865a1#diff-0f3118d4d839ee46a643c4a03ad907f78569918a6a3cc248ab072e0e45bcba0aR52-R64
While making sure they do not get overriden, like how Prisma does it:
export type ValuationWhereInput = {
AND?: Enumerable<ValuationWhereInput>
OR?: Enumerable<ValuationWhereInput>
NOT?: Enumerable<ValuationWhereInput>
...
estate?: XOR<EstateRelationFilter, EstateWhereInput> | null
}
export type EstateRelationFilter = {
is?: EstateWhereInput | null
isNot?: EstateWhereInput | null
}
And just replacing the <Model>WhereInput
here:
By the <Model>RelationFilter
.
There is no proper way to express OR
or XOR
in GraphQL, so I don't think it will be possible to emulate XOR<EstateRelationFilter, EstateWhereInput> | null
.
This is also why null
filters are causing issues, as you can't write uuid: StringFilter | null
or is: EstateWhereInput | null
either with GraphQL. If your model is expecting uuid: StringFilter
and you give it null
, it is interpreted as undefined
and then doesn't work properly when passed to Prisma Client.
That said, not being able to use null
filters is problematic - so I will open a new issue and look into ways we can possibly fix it.
Do you think fixing that issue would then take care of my initial problem and let me filter on one-to-one relationship existence, where the foreign key is not available on the model that is being filtered?
Yes, that's what I'm hopping for.
@Tenrys you can install prisma-appsync@1.0.0-preview.6.4
and try this:
query {
listValuations (
where: {
estate: { is: NULL } # or `isNot: NULL`
}
) {
uuid
estate {
uuid
}
}
}
Let me know if that solves your issue?
Works perfect for relationships, however I tried is
and isNot
on Int
, String
, Boolean
and came up with Prisma validation errors because is
and isNot
aren't handled on their filters. I imagine it's the same with Float
and other AWS scalars too.
Could make them use equals
and notEquals
on the Prisma side of things maybe?
Should work better now if you install prisma-appsync@1.0.0-preview.6.5
!
- Filtering by
null
on Relations can be done viais: NULL
andisNot: null
- Filtering by
null
on regular fields (String, Boolean, etc) can be done viaisNull: true
andisNull: false
- Filtering by
null
on required fields is not possible (e.g. iftitle
is required/mandatory it means it can't benull
)
A bug I found: if you try to use is
and isNot
from <Model>WhereInput
inside of a some
or every
, Prisma throws a validation error.