From: Mike Bayer Date: Wed, 17 Mar 2021 12:59:09 +0000 (-0400) Subject: Ensure entity or None returned from _entity_from_pre_ent_zero() X-Git-Tag: rel_1_4_1~6^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=484910a25bdc4ad4bb9d96ee68981a6fb631e1a8;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Ensure entity or None returned from _entity_from_pre_ent_zero() Fixed regression where the :meth:`_orm.Query.exists` method would fail to create an expression if the entity list of the :class:`_orm.Query` were an arbitrary SQL column expression. Fixes: #6076 Change-Id: I292dd5f527b2cbc1b76ca765b4ea321ef8535709 --- diff --git a/doc/build/changelog/unreleased_14/6076.rst b/doc/build/changelog/unreleased_14/6076.rst new file mode 100644 index 0000000000..c23b5ebdd5 --- /dev/null +++ b/doc/build/changelog/unreleased_14/6076.rst @@ -0,0 +1,8 @@ +.. change:: + :tags: bug, orm + :tickets: 6076 + + Fixed regression where the :meth:`_orm.Query.exists` method would fail to + create an expression if the entity list of the :class:`_orm.Query` were + an arbitrary SQL column expression. + diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index 4e2b4cdebb..8ad4092e68 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -22,6 +22,7 @@ import itertools import operator import types +from sqlalchemy.sql import visitors from . import exc as orm_exc from . import interfaces from . import loading @@ -197,7 +198,12 @@ class Query( elif "bundle" in ent._annotations: return ent._annotations["bundle"] else: - return ent + # label, other SQL expression + for element in visitors.iterate(ent): + if "parententity" in element._annotations: + return element._annotations["parententity"] + else: + return None def _only_full_mapper_zero(self, methname): if ( diff --git a/test/orm/test_query.py b/test/orm/test_query.py index 05ab160074..800c0ad5df 100644 --- a/test/orm/test_query.py +++ b/test/orm/test_query.py @@ -3925,6 +3925,36 @@ class ExistsTest(QueryTest, AssertsCompiledSQL): ") AS anon_1", ) + def test_exists_col_expression(self): + User = self.classes.User + sess = fixture_session() + + q1 = sess.query(User.id) + self.assert_compile( + sess.query(q1.exists()), + "SELECT EXISTS (" "SELECT 1 FROM users" ") AS anon_1", + ) + + def test_exists_labeled_col_expression(self): + User = self.classes.User + sess = fixture_session() + + q1 = sess.query(User.id.label("foo")) + self.assert_compile( + sess.query(q1.exists()), + "SELECT EXISTS (" "SELECT 1 FROM users" ") AS anon_1", + ) + + def test_exists_arbitrary_col_expression(self): + User = self.classes.User + sess = fixture_session() + + q1 = sess.query(func.foo(User.id)) + self.assert_compile( + sess.query(q1.exists()), + "SELECT EXISTS (" "SELECT 1 FROM users" ") AS anon_1", + ) + def test_exists_col_warning(self): User = self.classes.User Address = self.classes.Address