diff --git a/sqlalchemy_utils/functions/sort_query.py b/sqlalchemy_utils/functions/sort_query.py index 42ce022..650180d 100644 --- a/sqlalchemy_utils/functions/sort_query.py +++ b/sqlalchemy_utils/functions/sort_query.py @@ -52,6 +52,7 @@ class QuerySorter(object): if sort['entity'] and table.name != sort['entity']: continue return self.assign_entity_attr_order_by(entity, sort) + return self.query def assign_entity_attr_order_by(self, entity, sort): @@ -67,6 +68,11 @@ class QuerySorter(object): attr = attr.property.columns[0].name return self.query.order_by(sort['func'](attr)) + + # Check hybrid properties. + if hasattr(entity, sort['attr']): + return self.query.order_by(getattr(entity, sort['attr'])) + return self.query def parse_sort_arg(self, arg): diff --git a/tests/__init__.py b/tests/__init__.py index ce022c8..db65baa 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -4,6 +4,7 @@ import sqlalchemy as sa from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.ext.hybrid import hybrid_property from sqlalchemy_utils import InstrumentedList from sqlalchemy_utils import coercion_listener @@ -55,6 +56,18 @@ class TestCase(object): id = sa.Column(sa.Integer, primary_key=True) name = sa.Column(sa.Unicode(255)) + @hybrid_property + def articles_count(self): + return len(self.articles) + + @articles_count.expression + def articles_count(cls): + return ( + sa.select([sa.func.count(self.Article.id)]) + .where(self.Article.category_id == self.Category.id) + .label('article_count') + ) + class Article(self.Base): __tablename__ = 'article' id = sa.Column(sa.Integer, primary_key=True) diff --git a/tests/test_sort_query.py b/tests/test_sort_query.py index c1cd3d3..cbc87c1 100644 --- a/tests/test_sort_query.py +++ b/tests/test_sort_query.py @@ -93,3 +93,8 @@ class TestSortQuery(TestCase): query = self.session.query(self.Category) sorted_query = sort_query(query, '-article_count') assert 'article_count DESC' in str(sorted_query) + + def test_sort_by_hybrid_property(self): + query = self.session.query(self.Category) + query = sort_query(query, 'articles_count') + assert 'ORDER BY (SELECT count(article.id) AS count_1' in str(query)