Closed Speedy1991 closed 4 years ago
@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
@jkimbo I am migrating to graphene 3 and I am finding myself blocked by this.
There are a lot of places where I am using MyObjectType._meta.fields["my_enum_field"].type
to give type to my graphene inputs, and even in some places I have something like
MyGeneratedEnum = MyObjectType._meta.fields["my_enum_field"].type
class MyMutation(graphene.Mutation):
class Meta:
enum_input = graphene.List(MyGeneratedEnum)
this will give me a list of the enums, not a list of the values, which forces me add extra code that was previously done automatically.
Do I now have to transform the list of enums into a list of values for every case or is there a better alternative?
I also upgrading to v3 and running into a similar challenge as @DenisseRR.
By default when I inspect the schema type that is auto-generated for the enum Char fields, it does use the same type as MyObjectType._meta.fields["my_enum_field"].type
. And as such I thought it might be nice to use the same as my input type. However then get an error when actually passing it to my MyModelSerializer, as it is neither a value nor the same enum as I am actually using in the model field (graphene somehow turns my MyEnum
enum into MyAppMyModelMyEnumChoices
.
Any ideas or instructions on what to do? How is this intended?
Using enums as inputFields leads to errors
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
This code would work:
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