Add support for various order by types in make_order_by_deterministic

This commit is contained in:
Konsta Vesterinen
2014-10-22 13:08:34 +03:00
parent d4707c4c97
commit ec68aecbb7
4 changed files with 41 additions and 17 deletions

View File

@@ -4,6 +4,12 @@ Changelog
Here you can see the full list of changes between each SQLAlchemy-Utils release.
0.27.3 (2014-10-22)
^^^^^^^^^^^^^^^^^^^
- Added supported for various SQLAlchemy objects in make_order_by_deterministic (previosly this function threw exceptions for other than Column objects)
0.27.2 (2014-10-21)
^^^^^^^^^^^^^^^^^^^

View File

@@ -78,7 +78,7 @@ from .types import (
from .models import Timestamp
__version__ = '0.27.2'
__version__ = '0.27.3'
__all__ = (

View File

@@ -1,4 +1,3 @@
import six
import sqlalchemy as sa
from sqlalchemy.sql.expression import desc, asc
@@ -174,23 +173,18 @@ def make_order_by_deterministic(query):
return query
order_by = query._order_by[0]
if isinstance(order_by, sa.Column):
order_by_func = sa.asc
column = order_by
elif isinstance(order_by, sa.sql.expression.UnaryExpression):
if isinstance(order_by, sa.sql.expression.UnaryExpression):
if order_by.modifier == sa.sql.operators.desc_op:
order_by_func = sa.desc
else:
order_by_func = sa.asc
column = order_by.get_children()[0]
elif isinstance(order_by, six.string_types):
raise TypeError(
'Order by str is not supported. Use SA Column objects instead.'
)
else:
raise TypeError('Only simple columns in query order by are supported.')
column = order_by
order_by_func = sa.asc
if has_unique_index(column):
# Queries that are ordered by an already
if isinstance(column, sa.Column) and has_unique_index(column):
return query
base_table = get_tables(query._entities[0])[0]

View File

@@ -1,4 +1,3 @@
from pytest import raises
import sqlalchemy as sa
from sqlalchemy_utils.functions.sort_query import make_order_by_deterministic
@@ -18,12 +17,25 @@ class TestMakeOrderByDeterministic(TestCase):
sa.func.lower(name)
)
class Article(self.Base):
__tablename__ = 'article'
id = sa.Column(sa.Integer, primary_key=True)
author_id = sa.Column(sa.Integer, sa.ForeignKey('user.id'))
author = sa.orm.relationship(User)
User.article_count = sa.orm.column_property(
sa.select([sa.func.count()], from_obj=Article)
.where(Article.author_id == User.id)
.label('article_count')
)
self.User = User
def test_column_property(self):
query = self.session.query(self.User).order_by(self.User.email_lower)
with raises(TypeError):
make_order_by_deterministic(query)
query = make_order_by_deterministic(query)
assert_contains('lower("user".name), "user".id ASC', query)
def test_unique_column(self):
query = self.session.query(self.User).order_by(self.User.email)
@@ -52,8 +64,20 @@ class TestMakeOrderByDeterministic(TestCase):
def test_string_order_by(self):
query = self.session.query(self.User).order_by('name')
with raises(TypeError):
query = make_order_by_deterministic(query)
query = make_order_by_deterministic(query)
assert_contains('ORDER BY name, "user".id ASC', query)
def test_annotated_label(self):
query = self.session.query(self.User).order_by(self.User.article_count)
query = make_order_by_deterministic(query)
assert_contains('article_count, "user".id ASC', query)
def test_annotated_label_with_descending_order(self):
query = self.session.query(self.User).order_by(
sa.desc(self.User.article_count)
)
query = make_order_by_deterministic(query)
assert_contains('ORDER BY article_count DESC, "user".id DESC', query)
def test_query_without_order_by(self):
query = self.session.query(self.User)