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

how to pass in a json data struct? #101

Open
c-xlenz opened this issue Mar 1, 2024 · 2 comments
Open

how to pass in a json data struct? #101

c-xlenz opened this issue Mar 1, 2024 · 2 comments

Comments

@c-xlenz
Copy link

c-xlenz commented Mar 1, 2024

I have the following challenge:

I am getting data from a database in json format / as dict.
This works great when I am directly grabbing the data in the query and "upgrading" it to the defined and in meta class registered pedantic data model.

Example:

class GrapheneModel(PydanticObjectType):
    class Meta:
        model = PydanticModel

...
class Queries(ObjectType):
    examples = List(
        GrapheneModel
    )

    @staticmethod
    def resolve_examples(root, info, **kwargs):
        result = fetch_from_db() # return a list of dicts
        return [PydanticModel.model_validate(q) for q in result]

But I also have other cases where I come through an interface.
I can overlay the is_type_of method to get to the right GrapheneModel, but the data that comes in is then a dict, which does not work... Do you guys have an idea how the data can be upgraded within the Graphene Model?
I cannot do it in the interface as I do not know the type there...
Thanks for any advise.

@necaris
Copy link
Collaborator

necaris commented Mar 5, 2024

Thanks for your question! It looks like above you are creating PydanticModel instances resolve_examples method, but then it's returning dicts? That is definitely unexpected!

Without seeing more of your code, I'm finding it hard to give advice. Can you show where you're overriding is_type_of? Is it in the GrapheneModel definition? Can you show sample GraphQL queries that you want to run?

@c-xlenz
Copy link
Author

c-xlenz commented Mar 5, 2024

Thanks for your reply.
I will try to sketch a bit more code around my use case so that it might be better understandable ;)

I have a interface definition like this:

class DataInterface(Interface):
    id = String()

and a generic query endpoint

class Data(ObjectBase):
    data = Field(DataInterface)

class Queries(ObjectType):
    get_data = Field(
        Data,
        id=String(),
        description="Get the data for id",
    )

 @staticmethod
    def resolve_get_data (root, info, id, **kwargs):
        result = fetch_from_db(
            id
        )
        return result # this is json

So now back to the Rest... adapted from my previous post

class PydanticModel(pydantic.BaseModel):
    id: str
    something: str


class GrapheneModel(PydanticObjectType):
    class Meta:
        model = PydanticModel
        interfaces = (DataInterface,)


class Queries(ObjectType):
    examples = List(
        GrapheneModel
    )

    @staticmethod
    def resolve_examples(root, info, **kwargs):
        result = fetch_from_db() # return a list of dicts
        return [PydanticModel.model_validate(q) for q in result]

The query that works is

query {
     examples {
         id
         something
    }
}

What is not working is the following query:

query {
     get_data(id="1" {
         data {
             ... on GrapheneModel {
                 id
                 something
          }
       }
    }
}

One issue is that the GrapheneModel is_of_type from the PydanticGraphene base class is not hitting.
I could add something like this:
Note: I know that this will also cause problems to resolve the Model for the direct query case...but this can be handled. this is just for demonstration....

class GrapheneModel(PydanticObjectType):
    class Meta:
        model = PydanticModel
        interfaces = (DataInterface,)

     @classmethod
    def is_type_of(cls, root, info):
        # dummy to check if we should use this
        return ["1", "2", 3"].includes(root.get("id"))

Then the right Model (GrapheneModel) gets hit but the resulting values are "null".
But in any case the data comes in as dict and does not get "upgraded" to the correct model...

I hope this makes it more clear ;)
Thanks in advance

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

2 participants