Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pydantic - Graphene throws error for discriminator input objects. #72

Open
maheshchowdam523 opened this issue Apr 13, 2022 · 3 comments

Comments

@maheshchowdam523
Copy link

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?

@dima-dmytruk23
Copy link

@maheshchowdam523 try to define input and output schemas for Cat, Dog and Lizard models

@maheshchowdam523
Copy link
Author

@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)

@necaris
Copy link
Collaborator

necaris commented Apr 23, 2022

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants