.. changelog::
:version: 1.0.6
+ .. change::
+ :tags: bug, orm
+ :tickets: 3448
+
+ Fixed an unexpected-use regression whereby custom :class:`.Comparator`
+ objects that made use of the ``__clause_element__()`` method and
+ returned an object that was an ORM-mapped
+ :class:`.InstrumentedAttribute` and not explicitly a
+ :class:`.ColumnElement` would fail to be correctly
+ handled when passed as an expression to :meth:`.Session.query`.
+ The logic in 0.9 happened to succeed on this, so this use case is now
+ supported.
+
.. change::
:tags: bug, sql
:tickets: 3445
self.expr = column
self.namespace = namespace
search_entities = True
+ check_column = False
if isinstance(column, util.string_types):
column = sql.literal_column(column)
self._label_name = column.name
search_entities = False
+ check_column = True
_entity = None
elif isinstance(column, (
attributes.QueryableAttribute,
search_entities = False
self._label_name = column.key
column = column._query_clause_element()
+ check_column = True
if isinstance(column, Bundle):
_BundleEntity(query, column)
return
- elif not isinstance(column, sql.ColumnElement):
+
+ if not isinstance(column, sql.ColumnElement):
if hasattr(column, '_select_iterable'):
# break out an object like Table into
# individual columns
"SQL expression, column, or mapped entity "
"expected - got '%r'" % (column, )
)
- else:
+ elif not check_column:
self._label_name = getattr(column, 'key', None)
search_entities = True
from sqlalchemy.testing import fixtures
from sqlalchemy import inspect
+
class PropertyComparatorTest(fixtures.TestBase, AssertsCompiledSQL):
__dialect__ = 'default'
str(aliased(Foo).foo == 'ed'),
"foobar(foo_1.name) = foobar(:foobar_1)"
)
+
)
+class ComparatorTest(QueryTest):
+ def test_clause_element_query_resolve(self):
+ from sqlalchemy.orm.properties import ColumnProperty
+ User = self.classes.User
+
+ class Comparator(ColumnProperty.Comparator):
+ def __init__(self, expr):
+ self.expr = expr
+
+ def __clause_element__(self):
+ return self.expr
+
+ sess = Session()
+ eq_(
+ sess.query(Comparator(User.id)).order_by(Comparator(User.id)).all(),
+ [(7, ), (8, ), (9, ), (10, )]
+ )
+
+
# more slice tests are available in test/orm/generative.py
class SliceTest(QueryTest):
def test_first(self):