graphene-pydantic icon indicating copy to clipboard operation
graphene-pydantic copied to clipboard

Differentiate between default value and unset value in InputObjectType

Open konnerthg opened this issue 1 year ago • 1 comments

given the type

class PersonInput(InputObjectType):
    name = Field(String, required=False)

and the mutation

class UpdatePersonMutation:

    class Arguments:
        person_data = PersonInput(required=True)

    def mutate(cls, root, info, person_data):
        print(person_data)

how do i differentiate whether the query set the name field to None, explicitly? or just left it empty? Both yield the same output. and i understand that this is due to the default value in the input object. the output is:

{
    "name": None,
}

GQL query with None by default:

update_person(
    person_data: {
    }
)

GQL query with explicit None:

update_person(
    person_data: {
         name: null
    }
)

The context of my attempt: I'm writing a CRUD endpoint for a model, in this example it is Person. For the Update operation, I want the ability to delete a field (i.e. set it to None in the database). but also to leave it unmodified. to delete, the update would be {"name": None} and to leave unmodified, the update would be {}. note that i cannot send a exclude_none flag in the query, because the real query is much larger than my example, let's say

person_update_data = {
    "name": None,  # set "name" to None in the database
    "first_name": Eric,  # update this field in the database
    # no "last_name" field in the query, therefore do not modify "last_name" in the database
    # etc
}

What is the correct way to implement this in graphene? pydantic models for example, have an exclude_unset option. but I cannot find this in the graphene InputObjectType.

Thank you

konnerthg avatar Dec 12 '24 12:12 konnerthg

I don't think you can express this in GraphQL, per my reading of the spec. If you want to write this API as you've described, I think you'd need to have a "magic" value that represents None -- like using the string "__NULL__" to mean "set this field to None".

necaris avatar Dec 14 '24 03:12 necaris