Pydantic - Graphene throws error for discriminator input objects.
I am using graphene-pydantic to generate a GraphQL schema for my mutation. I have gone through the documentation and it's working fine for all the types but the problem is when I use discriminators in the modules. Below is the sample code with discriminators and that's throwing an error.
from graphene_pydantic import PydanticInputObjectType, PydanticObjectType
import graphene
from typing import Literal, Union
from pydantic import BaseModel, Field
class Cat(BaseModel):
pet_type: Literal['cat']
meows: int
class Dog(BaseModel):
pet_type: Literal['dog']
barks: float
class Lizard(BaseModel):
pet_type: Literal['reptile', 'lizard']
scales: bool
class Model(BaseModel):
pet: Union[Cat, Dog, Lizard] = Field(..., discriminator='pet_type')
n: int
# print(Model(pet={'pet_type': 'dog', 'barks': 3.14, 'eats': 'biscuit'}, n=1))
class Input(PydanticInputObjectType):
class Meta:
model = Model
# exclude specified fields
exclude_fields = ("id",)
class Output(PydanticObjectType):
class Meta:
model = Model
# exclude specified fields
exclude_fields = ("id",)
class CreateAnimal(graphene.Mutation):
class Arguments:
input = Input()
output = Output
@staticmethod
def mutate(parent, info, input):
print(input)
# save model here
return input
class Mutation(graphene.ObjectType):
createPerson = CreateAnimal.Field()
schema = graphene.Schema(mutation=Mutation)
print(schema)
The error getting from graphene is like below and it is like a generalized error.
File "\AppData\Local\Programs\Python\Python310\lib\site-packages\graphql\type\definition.py", line 1338, in fields raise TypeError(f"{self.name} fields cannot be resolved. {error}")
TypeError: Input fields cannot be resolved. The input field type must be a GraphQL input type.
Can someone help on this?
@maheshchowdam523 try to define input and output schemas for Cat, Dog and Lizard models
@dima-dmytruk23, I have tried defining the schemas for individual models as well, but still, the error is the same. If I remove discriminator it is working perfectly. Below is the code.
from graphene_pydantic import PydanticInputObjectType, PydanticObjectType
import graphene
from typing import Literal, Union
from pydantic import BaseModel, Field
class Cat(BaseModel):
pet_type: Literal['cat']
meows: int
class Dog(BaseModel):
pet_type: Literal['dog']
barks: float
class Lizard(BaseModel):
pet_type: Literal['reptile', 'lizard']
scales: bool
class Model(BaseModel):
pet: Union[Cat, Dog, Lizard] = Field(..., discriminator='pet_type')
n: int
print(Model(pet={'pet_type': 'dog', 'barks': 3.14, 'eats': 'biscuit'}, n=1))
class CatInput(PydanticInputObjectType):
class Meta:
model = Cat
fields = "__all__"
class DogInput(PydanticInputObjectType):
class Meta:
model = Dog
fields = "__all__"
class LizardInput(PydanticInputObjectType):
class Meta:
model = Lizard
fields = "__all__"
class CatOutput(PydanticObjectType):
class Meta:
model = Cat
fields = "__all__"
class DogOutput(PydanticObjectType):
class Meta:
model = Dog
fields = "__all__"
class LizardOutput(PydanticObjectType):
class Meta:
model = Lizard
fields = "__all__"
class Input(PydanticInputObjectType):
class Meta:
model = Model
# exclude specified fields
exclude_fields = ("id",)
class Output(PydanticObjectType):
class Meta:
model = Model
# exclude specified fields
exclude_fields = ("id",)
class CreateAnimal(graphene.Mutation):
class Arguments:
input = Input()
output = graphene.Field(Output)
@staticmethod
def mutate(parent, info, input):
print(input)
# save model here
return input
class Mutation(graphene.ObjectType):
createPerson = CreateAnimal.Field()
schema = graphene.Schema(mutation=Mutation)
print(schema)
It looks like this discriminator behavior is new in Pydantic 1.9 -- there appear to be a few new features that we don't currently support, including this. The way to handle this with graphene is to add a resolve_type classmethod to handle the discrimination -- a PR to do this would be welcome.