Skip to content

jorzel/graphene-sqlalchemy-sort

Repository files navigation

graphene-sqlalchemy-sort

Customized sorting for: Graphene SQLAlchemy library

Why do you need it? Graphene SQLAlchemy library has sort mechanism bult-in SQLALchemyConnectionField, however it enables ordering by using Model columns (Model corresponded to Node). It is not possible to sort collection using column from joined model / table or exploiting temporary query variable.

This solution is hugly inspired by: graphene-sqlalchemy-filter

class Example(Base):
    __tablename__ = "example"

    id = Column(Integer, primary_key=True, autoincrement=True)
    first_name = Column(String)
    second_name = Column(String)
    items = relationship("Item", uselist=True, lazy="dynamic")


class Item(Base):
    __tablename__ = "item"

    id = Column(Integer, primary_key=True, autoincrement=True)
    created = Column(DateTime)
    example_id = Column(
        Integer, ForeignKey("example.id", ondelete="CASCADE"), index=True
    )


class ExampleNode(SQLAlchemyObjectType):
    class Meta:
        model = Example
        interfaces = (graphene.relay.Node,)


class ExampleSort(SortSet):
    class Meta:
        model = Example
        fields = ["first_name", "second_name", "name", "item_created"]

    @classmethod
    def name_sort(cls, query):
        return query, case(
            [
                (Example.second_name.is_(None), Example.first_name),
                (Example.first_name.is_(None), Example.second_name),
            ],
            else_=Example.second_name,
        )

    @classmethod
    def item_created_sort(cls, query):
        if not is_model_joined(query, Item):
            query = query.join("items")
        return query, Item.created


class Query(graphene.ObjectType):
    examples = SQLAlchemyConnectionField(ExampleNode, sort=ExampleSort())

    def resolve_examples(self, info, **kwargs):
        query = info.context["session"].query(Example)
        if kwargs.get("sort"):
            query = ExampleSort().sort(query, kwargs["sort"])
        return query


schema = graphene.Schema(query=Query)

Sorting using default field

{
    examples (sort: {firstName: "ASC"}) {
        edges {
            node {
                firstName
            }
        }
    }
}

Sorting using custom field

{
    examples (sort: {name: "ASC"}) {
        edges {
            node {
                firstName
            }
        }
    }
}

Sorting using custom field with join

{
    examples (sort: {itemCreated: "DESC"}) {
        edges {
            node {
                firstName
            }
        }
    }
}

Releases

No releases published

Packages

No packages published

Languages