MichalLytek / typegraphql-prisma

Prisma generator to emit TypeGraphQL types and CRUD resolvers from your Prisma schema
https://prisma.typegraphql.com
MIT License
891 stars 113 forks source link

Argument 'where' of '*WhereUniqueInput' needs at least one of 'id' #466

Open t-rad679 opened 2 months ago

t-rad679 commented 2 months ago

Describe the Bug I'm trying to use an upsert operation and getting a error that doesn't seem to match what I'd expect on the update side. The error says that I need to specify "one of 'id'" property (which I'm not even sure how to acquire for the given object at this time without submitting another query to the database, but I will if I have to), but there is no 'id' field, either on the generated GraphQL schema or on the generated TypeGraphQL Input class. I have seen a similar error before, but it was legitimate and told me how there were multiple fields, and I was genuinely missing one that was needed. So this behavior is odd in three ways:

  1. It seems strange that the error message for multiple fields would be used for a case where a single field is required. This leads me to believe that something weird happened.
  2. Nowhere in the generated code can I even find the definition for the field it's looking for
  3. It is pretty rare in typegraphql-prisma to require an ID on a query/where. In fact, I've been surprised sometimes when I'm not even able to provide an ID when I want to. I often have to create a where clause to find the object I want to connect to the object being created. The only case where I've seen it requiring an ID is when I have a multi-field unique constraint that includes an ID. It just seems odd that in this specific case it would require an ID.

These things together lead me to believe that this is indeed a bug.

Note that this is occurring when I'm essentially trying to link two models together through a third model. In my case, it's Tags, Locations, and TagToObjectRelations. The tag field has a multi-field unique constraint for its userId and name.

To Reproduce I don't have time right at the moment or really until next week, but I will try to make a minimal reproduction repo. For now, the relevant repo is https://github.com/t-rad679/egrim

Here are some relevant pieces of code:

  1. CreateOrUpdateLocationForm.vue in that repo
  2. src/server/prisma/schema.prisma in that repo
  3. Generated TagToObjectRelationWhereUniqueInput.ts
  4. TagToObjectRelationWhereInput in generated-schema.graphql

Expected Behavior

  1. The field the error message is telling me to include exists on the generated GraphQL schema and, ideally, the generated TypeGraphQL Input class.
  2. I can achieve what I'm trying to achieve with a uniquely identifying where clause instead of an ID

Logs stack trace

Environment (please complete the following information):

Additional Context Add any other context about the problem here.

t-rad679 commented 2 months ago

Accidentally hit the create button before finishing. Editing the description now.

t-rad679 commented 2 months ago

Are you sure this deserves the label "question"? The fact that I'm receiving an error message telling me to include a field that doesn't exist in my query seems like a bug. I found a way around it before, but I'm running into it again in somewhat different circumstances.

MichalLytek commented 2 months ago

Is it related to #19?

t-rad679 commented 2 months ago

I don't think so, but I could be wrong. I've added dummy fields to my many-to-many relation tables to avoid that issue.

I will say, in this more recent issue I encountered, I realized I had forgotten to add a unique constraint on the field I was querying by. Once I added it, I was able to proceed. However, I still think it is a problem that the error message tells me to add a field that doesn't exist in the GraphQL API, and I think could generally be more descriptive.

I guess in some sense, this does sound like a similar problem to #19, and maybe they have the same underlying cause, but it still seems like a somewhat separate issue. It's not yet clear to me whether this issue only occurs on many-to-many relations, but that has been true in both of the cases I've encountered. This issue also seems to involve @unique and @@unique constraints in a way that the other issue does not.

On a side note, I also am now a bit confused by the architecture of the generated types/schema here. In particular, the *WhereUniqueInput types have all the fields (except the ID!), which suggests to me that you should be able to do any arbitrary query. Of course that query needs to return a single value for cases like update/upsert one, but I assumed the API would just return an error if it found more than one row. However, every time I've tried to query by a field that does not have a @unique or @@unique constraint applied to it, I get an error like this one, which suggests that you should only be able to do queries where you're guaranteed a unique result at the DB level.

So which of these behaviors is intended?

t-rad679 commented 2 months ago

Well, I at least figured out why the id field is not present in the generated types and schema: I have it listed in omitInputFieldsByDefault. I guess that does more or less make this into a "question". Though having a different error message in such a case would make sense, it seems less critical now. How the error message should look depends on the answer to my above question