Skip to content

Make a Relay ConnectionField optimized to work with Query #89

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

Closed
Fedalto opened this issue Nov 16, 2017 · 8 comments
Closed

Make a Relay ConnectionField optimized to work with Query #89

Fedalto opened this issue Nov 16, 2017 · 8 comments

Comments

@Fedalto
Copy link

Fedalto commented Nov 16, 2017

Graphene has the graphene.relay.ConnectionField, which slices a list/iterable to build the edges inside the Relay connection.
But it doesn't play well with DB queries. It calls len() with Query doesn't have.

graphene-sqlalchemy should have a implementation of the ConnectionField that is aware of the sqlalchemy's Query and use it to slice directly in the DB.

For now, I'm using this workaround:

class RelayConnectionField(graphene.relay.ConnectionField):
    @classmethod
    def resolve_connection(cls, connection_type, args, resolved):
        if isinstance(resolved, Query):
            len_ = resolved.count()
            connection = connection_from_list_slice(
                resolved,
                args,
                connection_type=connection_type,
                edge_type=connection_type.Edge,
                pageinfo_type=PageInfo,
                slice_start=0,
                list_length=len_,
                list_slice_length=len_,
            )
            connection.iterable = resolved
            return connection
        else:
            return super().resolve_connection(connection_type, args, resolved)
@Fedalto
Copy link
Author

Fedalto commented Nov 16, 2017

Similar/same issue to graphql-python/graphene#589

@sebastiandev
Copy link

Isn't this already covered here ?

    @classmethod
    def connection_resolver(cls, resolver, connection, model, root, info, **args):
        iterable = resolver(root, info, **args)
        if iterable is None:
            iterable = cls.get_query(model, info, **args)
        if isinstance(iterable, Query):
            _len = iterable.count()
        else:
            _len = len(iterable)

@Fedalto
Copy link
Author

Fedalto commented Jan 4, 2018

Indeed it is.
But if I used it I receives an error here

assert issubclass(_type, SQLAlchemyObjectType), (
"SQLAlchemyConnectionField only accepts SQLAlchemyObjectType types"
)
as I'm sending a graphene.relay.Connection instead of a SQLAlchemyObjectType.
Maybe I'm using it incorrectly?

@sebastiandev
Copy link

Yeah you need a SQLAlchemyObjectType there, everything gets down to an ObjectType eventually
Show us your Query definition to have a better idea of whats going on

@Fedalto
Copy link
Author

Fedalto commented Jan 4, 2018

Following graphene 2.0 (https://github.com/graphql-python/graphene/blob/master/UPGRADE-v2.0.md#node-connections), I defined explicit Connections.
My code is very similar to the one described in the link:

class User(SQLAlchemyObjectType):
    class Meta:
        model = UserModel
    name = String()

class UserConnection(relay.Connection):
    class Meta:
        node = User

class Group(SQLAlchemyObjectType):
    class Meta:
        model = GroupModel
    # Here, it works with the RelayConnectionField I posted in the issue.
    # But breaks if I change to SQLAlchemyConnectionField
    user_connection = RelayConnectionField(UserConnection)

class Query(ObjectType):
    group = Field(Group)

It does, however, work if I send the SQLAlchemyObjectType directly, like

user_connection = SQLAlchemyConnectionField(User)

But how can I add custom data to the Connection itself?

@sebastiandev
Copy link

You are mixing RelayConnectionFields with SqlAlchemy, You have to extend from SQLAlchemyConnectionField. I cant take a look right now, but check this as here we add fields to connections for counting purposes:
#58 (comment)

@Fedalto
Copy link
Author

Fedalto commented Jan 5, 2018

@sebastiandev, thanks for the help.

SQLAlchemyConnectionField indeed does handle the Query.
My issue now is how to subclass a Connection to add custom data to it.
Seems a duplicate of #65 (and there's a PR to fix it already #94).
I'm closing this.

@Fedalto Fedalto closed this as completed Jan 5, 2018
@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related topics referencing this issue.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 25, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants