summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/build/changelog/changelog_08.rst7
-rw-r--r--lib/sqlalchemy/orm/query.py20
-rw-r--r--test/orm/test_query.py15
3 files changed, 42 insertions, 0 deletions
diff --git a/doc/build/changelog/changelog_08.rst b/doc/build/changelog/changelog_08.rst
index 634ea4a95..96bbdb5a8 100644
--- a/doc/build/changelog/changelog_08.rst
+++ b/doc/build/changelog/changelog_08.rst
@@ -7,6 +7,13 @@
:version: 0.8.1
.. change::
+ :tags: feature, orm
+ :tickets: 2673
+
+ Added a convenience method to Query that turns a query into an
+ EXISTS subquery of the form EXISTS (SELECT 1 FROM ... WHERE ...)
+
+ .. change::
:tags: bug, mssql
:pullreq: 47
diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py
index b18e28abb..c80a430af 100644
--- a/lib/sqlalchemy/orm/query.py
+++ b/lib/sqlalchemy/orm/query.py
@@ -2373,6 +2373,26 @@ class Query(object):
kwargs.get('offset') is not None or
kwargs.get('distinct', False))
+ def exists(self):
+ """A convenience method that turns a query into an EXISTS subquery
+ of the form EXISTS (SELECT 1 FROM ... WHERE ...).
+
+ e.g.::
+
+ q = session.query(User).filter(User.name == 'fred')
+ session.query(q.exists())
+
+ Producing SQL similar to::
+
+ SELECT EXISTS (
+ SELECT 1 FROM users WHERE users.name = :name_1
+ ) AS anon_1
+
+ .. versionadded:: 0.8.1
+
+ """
+ return sql.exists(self.with_entities('1').statement)
+
def count(self):
"""Return a count of rows this Query would return.
diff --git a/test/orm/test_query.py b/test/orm/test_query.py
index ac9c95f41..3882ec4b5 100644
--- a/test/orm/test_query.py
+++ b/test/orm/test_query.py
@@ -1620,6 +1620,21 @@ class AggregateTest(QueryTest):
assert [User(name=u'jack',id=7), User(name=u'fred',id=9)] == sess.query(User).order_by(User.id).group_by(User).join('addresses').having(func.count(Address.id)< 2).all()
+
+class ExistsTest(QueryTest, AssertsCompiledSQL):
+
+ def test_exists(self):
+ User = self.classes.User
+ sess = create_session()
+ q1 = sess.query(User).filter(User.name == 'fred')
+ self.assert_compile(sess.query(q1.exists()),
+ 'SELECT EXISTS ('
+ 'SELECT 1 FROM users WHERE users.name = :name_1'
+ ') AS anon_1',
+ dialect=default.DefaultDialect()
+ )
+
+
class CountTest(QueryTest):
def test_basic(self):
users, User = self.tables.users, self.classes.User