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

What is intended way to implement Union? #117

Open
sVerentsov opened this issue Dec 11, 2019 · 3 comments
Open

What is intended way to implement Union? #117

sVerentsov opened this issue Dec 11, 2019 · 3 comments
Assignees
Labels

Comments

@sVerentsov
Copy link

Here is the schema that i am trying to implement:

type Text {
  id: ID
  content: String
}
type Image {
  id: ID
  image_url: String
  thumb_url: String
}
union Post = Text | Image
type User {
  id: ID
  posts: [Post]
}
type Query {
  users: [User]
}

and execute this query:

    {
        users {
            posts {
                ... on  Image {
                    image_url
                }
                ... on Text {
                    content
                }
            }
        }
    }

What I have tried:

  1. Mongoengine models: make PostModel as separate Document, inherit TextModel and ImageModel from it and reference PostModel from UserModel.
    Graphene objects: make types for Text, Image, User and Post as MongoengineObjectType.
    (full code here)
    This returns errors Unknown type "Image". and Unknown type "Text".
    In this case Post type has only fields Cls: String, id: ID.

  2. Mongoengine models: same.
    Graphene objects: inherit Post from graphene.Union and set Image and Text as types of that union.
    (full code here)
    This returns Cannot query field "posts" on type "User"..
    I suppose this happens because now graphene_mongo does not state that User.posts reference Post

So how should such schema be implemented?

@abawchen abawchen self-assigned this Dec 17, 2019
@abawchen abawchen added the good first issue Good for newcomers label Dec 17, 2019
@abawchen
Copy link
Collaborator

@sVerentsov : I will take a look, thanks.

@sVerentsov
Copy link
Author

sVerentsov commented Dec 17, 2019

I managed to solve this by explicitly stating posts field in User:

class User(MongoengineObjectType):
    class Meta:
        model = UserModel
    posts = graphene.Field(graphene.List(lambda: Post))


class Post(graphene.Union):
    class Meta:
        types = (Image, Text)

Full working code here

It is quite suprising that graphene-mongo resolves posts as references of ImageModel and TextModel automatically.

@abawchen
Copy link
Collaborator

class Reporter(mongoengine.Document):
meta = {'collection': 'test_reporter'}
id = mongoengine.StringField(primary_key=True)
first_name = mongoengine.StringField(required=True)
last_name = mongoengine.StringField(required=True)
email = mongoengine.EmailField()
awards = mongoengine.ListField(mongoengine.StringField())
articles = mongoengine.ListField(mongoengine.ReferenceField(Article))
embedded_articles = mongoengine.ListField(mongoengine.EmbeddedDocumentField(EmbeddedArticle))
embedded_list_articles = mongoengine.EmbeddedDocumentListField(EmbeddedArticle)
generic_reference = mongoengine.GenericReferenceField(
choices=[Article, Editor, ]
)

generic_reference = mongoengine.GenericReferenceField( 
         choices=[Article, Editor, ] 
     ) 

or you can use GenericReferenceField with choices to do it, but I have not verified ListField(mongoengine.GenericReferenceField()) works or not.

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

No branches or pull requests

2 participants