Add support for various order by types in make_order_by_deterministic
This commit is contained in:
@@ -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)
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
@@ -78,7 +78,7 @@ from .types import (
|
||||
from .models import Timestamp
|
||||
|
||||
|
||||
__version__ = '0.27.2'
|
||||
__version__ = '0.27.3'
|
||||
|
||||
|
||||
__all__ = (
|
||||
|
@@ -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]
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user