I had a problem saving the null values in the mutations. Is it possible to implement functionality to get_argument_values function could distinguish passed null value and not passed value?
I think it can be implemented similar to the executor.ececute_fields using Undefined.
Hi @prokofiev!
You can actually use the default_value in the Argument and set another default than None.
So currently you can do:
class Undefined(object): pass
class Query(graphene.ObjectType):
field = graphene.String(
input=graphene.String(default_value=Undefined)
)
It might be interesting to set Undefined as default_value in a GraphQLArgument in graphql-core instead of None, but probably this is something that we should investigate a little bit further :)
Hi @syrusakbary !
Thanks for answer, but default_value will not be able to solve my problem.
I try to describe the problem in more detail:
class Foo(models.Model):
''' Example model with nullable field '''
not_null = models.CharField(max_length=10)
nullable = models.CharField(max_length=10, null=True)
Next my use cases:
1) Insert with default null value
mutation InsertFoo{
saveFoo (input:{
clientMutationId:"1"
notNull:"value"
}) {
...
}
}
2) Update nullable field (set "value"), not_null ignored
mutation UpdateFoo{
saveFoo (input:{
clientMutationId:"1"
id:"id"
nullable: "value"
}) {
...
}
}
3) Update nullable field (set null), not_null ignored
mutation UpdateFoo{
saveFoo (input:{
clientMutationId:"1"
id:"id"
nullable: null
}) {
...
}
}
How can I use "default_value" to set the nullable field to null (case 3)?
Hey @prokofiev, after thinking about this I realized this could be approached in a easier way. As input is a dict, you could check if not_null in exists in input.
Something like
@classmethod
def mutate_and_get_payload(cls, input, context, info):
not_null = 'UNDEFINED'
if 'not_null' in input:
# ....
not_null = input['not_null']
# ....
Does that make sense?
After checking, I realized that this query:
mutation UpdateFoo{
saveFoo (input:{
clientMutationId:"1"
id:"id"
nullable: null
}) {
...
}
}
Is actually not valid as null is not a valid value in GraphQL.
https://github.com/graphql-python/graphql-core/blob/master/graphql/language/tests/test_parser.py#L80-L84
For this reason I guess that some client's check when the value is null and then skip it (Relay?).
As an extra exercise, I checked that arguments and input fields that are not provided don't fill the dictionary with None values:
def test_does_not_include_arguments_that_were_not_set():
InputObject = GraphQLInputObjectType(
name='InputObject',
fields={
'value': GraphQLInputObjectField(GraphQLString, default_value=None),
'other': GraphQLInputObjectField(GraphQLString, default_value=None)
}
)
def resolver(data, args, *_):
print args
return 'other' in args['c']
schema = GraphQLSchema(GraphQLObjectType(
'Type',
{
'field': GraphQLField(
GraphQLInt,
resolver=resolver,
args={
'a': GraphQLArgument(GraphQLBoolean),
'b': GraphQLArgument(GraphQLBoolean),
'c': GraphQLArgument(InputObject),
'd': GraphQLArgument(GraphQLInt),
'e': GraphQLArgument(GraphQLInt),
}
)
}
))
ast = parse('{ field(c: {value: "3"}) }')
result = execute(schema, ast)
assert result.data == {
'field': False
}
If you can provide more insights that I might be missing please let me know.
null value may be passed like this:
mutation UpdateFoo($var1:String!){
saveFoo (input:{
clientMutationId:"1"
id:"id"
nullable: $var1
}) {
...
}
}
variables:
{"var1": null}
Hey @prokofiev , did you find a workaround for this?
I'm struggling with exactly the same problem and am very interested in your approach. The least hack I could come up with, is to always require all arguments and then use 'input.get('myVar', None)' to retrieve them in 'mutate_and_get_payload()'.
Even setting the field to be required and having a default value will not make it appear in the input dict...
Hi @nuschk.
I found solution for my case. It's monkey patch but it works...
You can see my patch here
Call apply from any place when initialize your app.
If somebody knows how to fix it more correctly, please let me know.
@prokofiev Hehe, thanks for the snippet. Will look into it.
@syrusakbary have you seen this pull request?
https://github.com/facebook/graphql/pull/83
graphql now supports nullable types. Can we get some support for this in graphene?
Any progress on this?
@NiekHoekstra Does a PR exist yet for this? If not are you willing to take the patch and turn it into a PR? :)
We are having the same problem!
This issue is solved in graphene 2.0 and should be closed
Does someone have an example for 2.0?
@BossGrand I am still having this problem with null values.
If my javascript client sends a mutation with those variables:
{"id": 4, "titulo": "TITULO", "resenha": "RESENHA", "autorId": 1}
my server receives this as **args (at mutate function):
{'autor_id': 1, 'id': 4, 'resenha': 'RESENHA', 'titulo': 'TITULO'}
However, if the client sends this:
{"id": 4, "titulo": "TITULO", "resenha": null, "autorId": null}
My python **args param receives only 2 keys/values:
{'id': 4, 'titulo': 'TITULO'}
(where I would expect receiving {'id': 4, 'titulo': 'TITULO', 'resenha': None, 'autorId': None})
My packages versions:
➜ pip freeze | grep -i graph
Flask-GraphQL==1.4.1
graphene==2.0
graphene-sqlalchemy==2.0.0
graphql-core==2.0
graphql-relay==0.4.5
Should this issue be reopened ?
Thanks in advance
@rdemetrescu i get the same thing... so not sure if this is really fixed.
@arif-hanif, just noticed that mutations using relay work perfectly.
I have seen this query:
mutation myMutation {
editIt(Input: {id: "AFJS", title: null}) {
It {id}
}
}
fail with:
'Syntax Error GraphQL request (3:112) Unexpected Name "null"
However when I pass title as a "variable" it does work.
graphql-core is responsible for the query parsing so that is where adding null to the language will need to be added. Looks like there is already a pull request open to implement it: https://github.com/graphql-python/graphql-core/pull/119
@rdemetrescu I can't reproduce your issue. If you are still having problems can you open a new issue with everything needed to reproduce it?
Closing this for now
@jkimbo Hi, this is still unsolved and the link to the graphql-core pull request is dead. Can you please advise where this is/was tracked? Thanks!
@brabeji we will shortly be releasing graphene v3 that is based on graphql-core v3 which is a complete rewrite and has support for null values. You can try out the beta release now. Release notes are here: https://github.com/graphql-python/graphene/wiki/v3-release-notes
Most helpful comment
@syrusakbary have you seen this pull request?
https://github.com/facebook/graphql/pull/83
graphql now supports nullable types. Can we get some support for this in graphene?