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.
|
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)
|
0.27.2 (2014-10-21)
|
||||||
^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
@@ -78,7 +78,7 @@ from .types import (
|
|||||||
from .models import Timestamp
|
from .models import Timestamp
|
||||||
|
|
||||||
|
|
||||||
__version__ = '0.27.2'
|
__version__ = '0.27.3'
|
||||||
|
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
|
@@ -1,4 +1,3 @@
|
|||||||
import six
|
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
from sqlalchemy.sql.expression import desc, asc
|
from sqlalchemy.sql.expression import desc, asc
|
||||||
|
|
||||||
@@ -174,23 +173,18 @@ def make_order_by_deterministic(query):
|
|||||||
return query
|
return query
|
||||||
|
|
||||||
order_by = query._order_by[0]
|
order_by = query._order_by[0]
|
||||||
if isinstance(order_by, sa.Column):
|
if isinstance(order_by, sa.sql.expression.UnaryExpression):
|
||||||
order_by_func = sa.asc
|
|
||||||
column = order_by
|
|
||||||
elif isinstance(order_by, sa.sql.expression.UnaryExpression):
|
|
||||||
if order_by.modifier == sa.sql.operators.desc_op:
|
if order_by.modifier == sa.sql.operators.desc_op:
|
||||||
order_by_func = sa.desc
|
order_by_func = sa.desc
|
||||||
else:
|
else:
|
||||||
order_by_func = sa.asc
|
order_by_func = sa.asc
|
||||||
column = order_by.get_children()[0]
|
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:
|
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
|
return query
|
||||||
|
|
||||||
base_table = get_tables(query._entities[0])[0]
|
base_table = get_tables(query._entities[0])[0]
|
||||||
|
@@ -1,4 +1,3 @@
|
|||||||
from pytest import raises
|
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
|
||||||
from sqlalchemy_utils.functions.sort_query import make_order_by_deterministic
|
from sqlalchemy_utils.functions.sort_query import make_order_by_deterministic
|
||||||
@@ -18,12 +17,25 @@ class TestMakeOrderByDeterministic(TestCase):
|
|||||||
sa.func.lower(name)
|
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
|
self.User = User
|
||||||
|
|
||||||
def test_column_property(self):
|
def test_column_property(self):
|
||||||
query = self.session.query(self.User).order_by(self.User.email_lower)
|
query = self.session.query(self.User).order_by(self.User.email_lower)
|
||||||
with raises(TypeError):
|
query = make_order_by_deterministic(query)
|
||||||
make_order_by_deterministic(query)
|
assert_contains('lower("user".name), "user".id ASC', query)
|
||||||
|
|
||||||
def test_unique_column(self):
|
def test_unique_column(self):
|
||||||
query = self.session.query(self.User).order_by(self.User.email)
|
query = self.session.query(self.User).order_by(self.User.email)
|
||||||
@@ -52,8 +64,20 @@ class TestMakeOrderByDeterministic(TestCase):
|
|||||||
|
|
||||||
def test_string_order_by(self):
|
def test_string_order_by(self):
|
||||||
query = self.session.query(self.User).order_by('name')
|
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):
|
def test_query_without_order_by(self):
|
||||||
query = self.session.query(self.User)
|
query = self.session.query(self.User)
|
||||||
|
Reference in New Issue
Block a user