prisma: `upsert()` `where` is defined as `number | undefined` but does not allow `undefined` to not select anything
Hi,
the where object shows a hint that it is of type number | undefined, but I am unable to use undefined.
I must specify where: {unique_id: 0} to get it working or am I missing something?
About this issue
- Original URL
- State: open
- Created 3 years ago
- Reactions: 49
- Comments: 29 (4 by maintainers)
I want to give a big š to this.
Hereās my use case:
Which produces this error when
choice.idis undefined:But I can get it to work by changing where:
{ id: choice.id }to where:{ id: choice.id || 0 }If I have a specific id then 99% of the time that record will exist. Itās
id = undefinedwhen I need upsert. So if upsert doesnāt allowundefined, then upsert is useless in this case (unless we do a hack like{where: {id: user.id || 0}})I just wanted to chime in for option 1.
I ran into this issue when using UUIDs as id:
where: { id: modelId || 0 }andwhere: { id: modelId || null }give type errors as expected. Using thezeroUUID works:where: { id: organizationId || '00000000-0000-0000-0000-000000000000' }, but thats rather awkward and defies the use of an upsert, right?My expectation as Prisma user is that
id: undefinedshould work.Iām running into this issue as well. I have a table with a UUID string as primary key. When I do an upsert on this table, I use a where clause like
where: { id: data?.id }. This gives the error stated by the OP when the id is undefined. As a workaround I usewhere: { id: data.id || ""}but this is technically not correct. An id could be āā when a record was explicitly added with āā as the id. Then the upsert would update that record instead of creating a new one.I think the comment of @Johnrobmiller is spot on. The definition of āundefinedā in a where clause should not be the same as in a create/update object.
As a workaround, maybe you could make a where clause not be required in the upsert method? When the where clause is omitted, then always perform a create. Then we could do something like
where: data.id ? { id: data.id } : undefined. Not very user friendly, but at least an alternative.By giving a random uuid you can also get rid of type errors and possible unexpected updates.
Hmm, this is a tricky one because
undefinedso far has consistently meant exclude from the results.I agree with @flybayer though that
id = undefinedis when you need actually want to upsert.Iām wondering 2 things:
upsertwith an emptywhereclause always try tocreate? This would be consistent with our current approach.wheretype to not allow undefined since it triggers a validation error anyways. Then the proper way isuser.id || 0oruser.id || "".Any other ideas?
Not a big fan of the first point, if that was the case we should just use update then. I like the second point though.
Just updating the docs would be a valid solution imo., as the example given upsert a user where id = 1, but how often are idās supplied in a create?
maybe?
@DanStevensonDev yep I imagine a few of us have the same dirty little hard coded
00000000-0000-0000-0000-000000000000in our code because of this oddity in the way prisma upsert works.As you say, simple solution would be to allow
undefinedand just do a ācreateā if there is nowhereclause.+1 to making the
whereproperty optional on theupsertoptions and doing a create if it is not passed⦠as mentioned earlier, this issue is particularly annoying if you use UUID primary keysjust ran into this, the error is very vague as well
Argument where of type <modelName>WhereUniqueInput needs at least one argument. Available args are listed in green.
ā¦what?
I donāt see any problem with the first point. If the ID comes from an user input, then it should be possible to pass
undefined. I mean, itās exactly the point of an upsert: āif the id is not provided or the record doesnāt exists, create, otherwise updateā.For data it works but not in
whereclause. This causes an errorThis works
I know that this is a work around, I apologize for pretending to offer a solution, I just made an extra suggestion instead of a usage like ā00000000-0000-0000-0000-0000-000000000000ā (the same non-zero probability is here) but I could not express it correctly.
I agree that we need a real solution by Prisma.
@melihkizmaz by doing so you are introducing a non-zero probability of operation failure, no matter how small the probability is, you are now responsible for handling that failure case. Which is going to be nasty to deal with.
We need real solution, not some hack to get around it, Prisma needs to keep up with these requests, we are not asking for much here.
Of course @janpio , thank you. I moved on but when Iāll have time Iāll open a new issue
So, Iām replying again to say that right now
upsertis not working with MongoDB and thereās no workaround. As @ohueter is pointing out, you have to pass a valid value and in case of MongoDB it must be an ObjectId. I really think this is not a secondary issue and it should be addressed since a core API is completely not working. Even if Iād like to see theundefinedoption to be implemented, Iād appreciate anything that works. Iād also provide a PR as soon as a design decision is takenRegarding the consistency in the Prisma api that āundefinedā translates to āomit thisā, true, Prisma could just ask the user to only use āundefinedā values in this specific way, but this has problems:
So from my viewpoint, it might be good to refactor some of the prisma api to let āundefinedā simply mean āundefinedā and not āomit this valueā