Skip to content

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

Open
@maheshchowdam523

Description

@maheshchowdam523

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?

Activity

dima-dmytruk23

dima-dmytruk23 commented on Apr 19, 2022

@dima-dmytruk23

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

maheshchowdam523

maheshchowdam523 commented on Apr 23, 2022

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

necaris commented on Apr 23, 2022

@necaris
Collaborator

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Pydantic - Graphene throws error for discriminator input objects. · Issue #72 · graphql-python/graphene-pydantic