From b2bc0c8e4138ccef4834a415f7be9012e1c6286e Mon Sep 17 00:00:00 2001 From: Federico Caselli Date: Sat, 4 Dec 2021 23:08:05 +0100 Subject: The where method of exists now accepts multiple cluase. Support multiple clause elements in the :meth:`_sql.Exists.where` method, unifying the api with the on presented by a normal :func:`_sql.select` construct. Fixes: #7386 Change-Id: I5df20478008cd5167053d357cbfad8a641c62b44 --- doc/build/changelog/unreleased_14/7386.rst | 7 +++++++ lib/sqlalchemy/sql/selectable.py | 10 ++++++++-- test/sql/test_compiler.py | 8 ++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 doc/build/changelog/unreleased_14/7386.rst diff --git a/doc/build/changelog/unreleased_14/7386.rst b/doc/build/changelog/unreleased_14/7386.rst new file mode 100644 index 000000000..e344453c8 --- /dev/null +++ b/doc/build/changelog/unreleased_14/7386.rst @@ -0,0 +1,7 @@ +.. change:: + :tags: usecase, sql + :tickets: 7386 + + Support multiple clause elements in the :meth:`_sql.Exists.where` method, + unifying the api with the on presented by a normal :func:`_sql.select` + construct. diff --git a/lib/sqlalchemy/sql/selectable.py b/lib/sqlalchemy/sql/selectable.py index a82a76e53..ca3ccc6bc 100644 --- a/lib/sqlalchemy/sql/selectable.py +++ b/lib/sqlalchemy/sql/selectable.py @@ -6490,6 +6490,9 @@ class Exists(UnaryExpression): See :func:`_sql.exists` for a description of usage. + An ``EXISTS`` clase can also be construed from a :func:`_sql.select` + instance by calling :meth:`_sql.SelectBase.exists`. + """ _from_objects = [] @@ -6528,6 +6531,9 @@ class Exists(UnaryExpression): :ref:`tutorial_exists` - in the :term:`2.0 style` tutorial. + :meth:`_sql.SelectBase.exists` - method to transform a ``SELECT`` to an + ``EXISTS`` clause. + """ # noqa E501 if args and isinstance(args[0], (SelectBase, ScalarSelect)): s = args[0] @@ -6642,7 +6648,7 @@ class Exists(UnaryExpression): e.element = self._regroup(lambda element: element.select_from(*froms)) return e - def where(self, clause): + def where(self, *clause): """Return a new :func:`_expression.exists` construct with the given expression added to its WHERE clause, joined to the existing clause via AND, if any. @@ -6655,7 +6661,7 @@ class Exists(UnaryExpression): """ e = self._clone() - e.element = self._regroup(lambda element: element.where(clause)) + e.element = self._regroup(lambda element: element.where(*clause)) return e diff --git a/test/sql/test_compiler.py b/test/sql/test_compiler.py index 6779ea7bf..55c2b07c4 100644 --- a/test/sql/test_compiler.py +++ b/test/sql/test_compiler.py @@ -1241,6 +1241,14 @@ class SelectTest(fixtures.TestBase, AssertsCompiledSQL): "SELECT NOT (NOT (EXISTS (SELECT 1))) AS anon_1", ) + self.assert_compile( + exists(42) + .select_from(table1) + .where(table1.c.name == "foo", table1.c.description == "bar"), + "EXISTS (SELECT 42 FROM mytable WHERE mytable.name = :name_1 " + "AND mytable.description = :description_1)", + ) + def test_exists_method(self): subq = ( select(func.count(table2.c.otherid)) -- cgit v1.2.1