Using enums as inputFields leads to errors
SalutationEnum = graphene.Enum('SalutationEnum', [('Man', 0), ('Woman', 1)])
class MyModel(Model):
salutation = models.IntegerField()
class SomeInput(graphene.InputObjectType):
salutation = SalutationEnum(required=True)
class MyMutation(graphene.Mutation):
...
class Arguments:
input = SomeInput(required=True)
...
mutate(self, info, input):
...
myModel.salutation = input.salutation
myModel.save()
leads to
"message": "Field 'salutation' expected a number but got <SalutationEnum.Man: 0>.",
I think the problem is, that SalutationEnum is not resolved to its value (this worked in graphene 2.x) but resolved to a SalutationEnum
salutation: SalutationEnum{
name: 'Man'
value: 0
}
This code would work:
myModel.salutation = input.salutation.value
myModel.save()
But I don't think it is intended to call value on each enum?
Edit:
Just found #1151 - looks like this is intended??
graphene: 3.0.0b5
@Speedy1991 What does your query look like?
mutation MyMutation($input: SomeInput!){
myMutation(input: $input){
success
}
}
variables (typescriped with codegen):
{"input": {"salutation": SalutationEnum.Man}}
Codegen generated type:
export enum SalutationEnum {
Man = "Man",
Woman= "Woman",
}
typescript generated with:
apollo codegen:generate --outputFlat --config apollo.config.js --target typescript --tagName=gql --globalTypesFile=src/types/graphql-global-types.ts src/types
Ah ok @Speedy1991 this is the expected behaviour. Starting in Graphene 3 enum inputs to mutations are the enum member rather than the enum value (which was the case in Graphene 2). See https://github.com/graphql-python/graphene/pull/1153 To get the enum value you will have to access .value on the member in your mutation.
Does that make sense?
Yea that makes sense.
Some magic is no more working with this approach. That's a pitty.
E.g. Django.:
def mutate(self, info, id, **kwargs):
instance = Model.objects.get(id=id)
for k, v in kwargs.items():
setattr(instance, k, v)
instance.save(update_fields=[kwargs.keys()])
My workaround is now:
for k, v in kwargs.items():
try:
v = v.value
except AttributeError:
pass
setattr(instance, k, v)
Ah ok I see. You can also check if the value is an enum before trying to access .value.
Anyway closing this issue.
Hey @jkimbo
Just found another issue with enums:
MemberRoleEnum = graphene.Enum('MemberRoleEnum', [('Vertrieb', 'staff'), ('Administrator', 'admin')])
class MemberType(DjangoObjectType):
role = MemberRoleEnum(required=False)
def resolve_role(self, info):
return self.role # 'admin'
Query MemberType with
{ member { role }}
Leads to
{
"message": "Expected a value of type 'MemberRoleEnum' but received: 'MemberRoleEnum.Administrator'",
"payload": null,
"code": 500,
"messages": [],
"messageDict": {},
"exception": [
"TypeError"
],
"trace": [
" File \"C:\\Users\\Speedy\\git\\proj\\_lib\\venv\\lib\\site-packages\\graphql\\execution\\execute.py\", line 631, in complete_value_catching_error\n completed = self.complete_value(\n",
" File \"C:\\Users\\Speedy\\git\\proj\\_lib\\venv\\lib\\site-packages\\graphql\\execution\\execute.py\", line 730, in complete_value\n return self.complete_leaf_value(cast(GraphQLLeafType, return_type), result)\n",
" File \"C:\\Users\\Speedy\\git\\proj\\_lib\\venv\\lib\\site-packages\\graphql\\execution\\execute.py\", line 815, in complete_leaf_value\n raise TypeError(\n"
]
}
That worked back in graphene2. Any idea whats going wrong here?
Running
graphene==3.0.0b6
graphene_django==3.0.0b6
@Speedy1991 I can't reproduce that issue. Running this works for me:
def test_enum_issue_1277():
MemberRoleEnum = Enum(
"MemberRoleEnum", [("Vertrieb", "staff"), ("Administrator", "admin")]
)
class Query(ObjectType):
role = MemberRoleEnum(required=False)
def resolve_role(self, info):
return self["role"] # 'admin'
schema = Schema(Query)
result = schema.execute("{ role }", root={"role": "admin"})
assert not result.errors
assert result.data == {
"role": "Administrator",
}
Just tried your example and I can confirm this is working
Just debuged deep into this process and found that I wrote a wrong value into the DB when I tried around with the enums.
That was really confusing because the database value was MemberRoleEnum.Administrator and not admin.
Btw. great work @jkimbo & contributors - looking foward the 3.0 release