From: Mike Bayer Date: Thu, 27 Aug 2020 19:50:47 +0000 (-0400) Subject: Raise NotImplemenedError for association proxy __clause_element__ X-Git-Tag: rel_1_3_20~34 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=99bb0fc9e8d57c2dce3d9b794bc9ab73a2059bec;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Raise NotImplemenedError for association proxy __clause_element__ It's not possible right now to use an association proxy element as a plain column expression to be SELECTed from or used in a SQL function. An informative error is now raised when this occurs. Fixes: #5542 Change-Id: I334e767ebc0b56c1dccc4a1e5185b0435af77b93 (cherry picked from commit d78686b4f109fdc78ca6239e5a5af791717bc48d) --- diff --git a/doc/build/changelog/unreleased_13/5541.rst b/doc/build/changelog/unreleased_13/5541.rst new file mode 100644 index 0000000000..73bb4b69b8 --- /dev/null +++ b/doc/build/changelog/unreleased_13/5541.rst @@ -0,0 +1,8 @@ +.. change:: + :tags: bug, ext, associationproxy + :tickets: 5541, 5542 + + It's not possible right now to use an association proxy element as a plain + column expression to be SELECTed from or used in a SQL function. An + informative error is now raised when this occurs. + diff --git a/lib/sqlalchemy/ext/associationproxy.py b/lib/sqlalchemy/ext/associationproxy.py index 94c0f81eb5..5151ddb2a3 100644 --- a/lib/sqlalchemy/ext/associationproxy.py +++ b/lib/sqlalchemy/ext/associationproxy.py @@ -421,6 +421,12 @@ class AssociationProxyInstance(object): def _comparator(self): return self._get_property().comparator + def __clause_element__(self): + raise NotImplementedError( + "The association proxy can't be used as a plain column " + "expression; it only works inside of a comparison expression" + ) + @classmethod def _cls_unwrap_target_assoc_proxy(cls, target_class, value_attr): attr = getattr(target_class, value_attr) diff --git a/test/ext/test_associationproxy.py b/test/ext/test_associationproxy.py index 2054e023cd..41d1bdd45e 100644 --- a/test/ext/test_associationproxy.py +++ b/test/ext/test_associationproxy.py @@ -4,6 +4,7 @@ import pickle from sqlalchemy import cast from sqlalchemy import exc from sqlalchemy import ForeignKey +from sqlalchemy import func from sqlalchemy import inspect from sqlalchemy import Integer from sqlalchemy import MetaData @@ -1660,6 +1661,26 @@ class ComparatorTest(fixtures.MappedTest, AssertsCompiledSQL): eq_(str(proxy_sql), str(direct_sql)) eq_(q_proxy.all(), q_direct.all()) + def test_no_straight_expr(self): + User = self.classes.User + + assert_raises_message( + NotImplementedError, + "The association proxy can't be used as a plain column expression", + func.foo, + User.singular_value, + ) + + # this raises the same NotImplementedError as above in 1.4 + # because we consistently call __clause_element__(). 1.3 not + # quite there :) + assert_raises_message( + exc.InvalidRequestError, + "SQL expression, column, or mapped entity expected ", + self.session.query, + User.singular_value, + ) + def test_filter_any_criterion_ul_scalar(self): UserKeyword, User = self.classes.UserKeyword, self.classes.User