sqlalchemy exists for query
Asked Answered
R

7

86

How do I check whether data in a query exists?

For example:

users_query = User.query.filter_by(email='[email protected]')

How I can check whether users with that email exist?

I can check this with

users_query.count()

but how to check it with exists?

Rubenrubens answered 4/10, 2011 at 10:0 Comment(0)
J
102

The following solution is a bit simpler:

from sqlalchemy.sql import exists

print session.query(exists().where(User.email == '...')).scalar()
Jernigan answered 11/11, 2012 at 23:1 Comment(2)
Note that this would give wrong results for polymorphic types. When filtering on both parent and child attributes, the resulting query will select from cartesian product (outer join) of tables. To fix it, you should manually set FROM clause via select_from: e = exists(select([1]).select_from(User).where(and_(User.email == '...', ...))).select()Priapism
@aikoven: your suggestion results in a Every derived table must have its own alias error. Adding exists(…).select().alias('foo') fixed it (see alias() function).Avunculate
F
43

The most acceptable and readable option for me is

session.query(<Exists instance>).scalar()

like

session.query(User.query.filter(User.id == 1).exists()).scalar()

which returns True or False.

Fitts answered 31/1, 2017 at 7:26 Comment(3)
Also, note that some databases such as SQL Server don’t allow an EXISTS expression to be present in the columns clause of a SELECT. To select a simple boolean value based on the exists as a WHERE, use sqlalchemy.literal: session.query(literal(True)).filter(q.exists()).scalar()Waterrepellent
This throws following exception: AttributeError: type object 'User' has no attribute 'query'Nilgai
The .query attribute is specific to Flask-SQLAlchemy. You'd use session.query(session.query(User).filter(User.id == 1).exists()).scalar().Rosebud
A
16

There is no way that I know of to do this using the orm query api. But you can drop to a level lower and use exists from sqlalchemy.sql.expression:

from sqlalchemy.sql.expression import select, exists

users_exists_select = select((exists(users_query.statement),)) 
print engine.execute(users_exists_select).scalar()
Agentive answered 4/10, 2011 at 11:54 Comment(0)
T
16

2021 Answer for SqlAlchemy 1.4

Refrain from calling .query and instead use select directly chained with .exists as follows:

from sqlalchemy import select

stmt = select(User).where(User.email=="[email protected]").exists()

Source: https://docs.sqlalchemy.org/en/14/core/selectable.html?highlight=exists#sqlalchemy.sql.expression.exists

Triiodomethane answered 25/10, 2021 at 21:18 Comment(2)
This is SqlAlchemy 1.4Cilicia
Attempting to execute this will result in an error because Exists is a clause, not a statement. You need to wrap it in select().Jd
G
4

For SQL Server, I had to do this:

from sqlalchemy.sql.expression import literal

result = session.query(literal(True)).filter(
    session.query(User)
    .filter_by(email='...')
    .exists()
).scalar()
print(result is not None)

# Resulting query:
# SELECT 1
# WHERE EXISTS (SELECT 1 
# FROM User
# WHERE User.email = '...')

But it's much simpler without EXISTS:

result = (
    session.query(literal(True))
    .filter(User.email == '...')
    .first()
)
print(result is not None)

# Resulting query:
# SELECT TOP 1 1
# FROM User
# WHERE User.email = '...'
Gogetter answered 3/10, 2019 at 18:19 Comment(2)
Same for Oracle 12c. Thank you for the solutionSoggy
session.query(cls).filter_by(**kwargs).first() is not None would also work, without importing literal, at least for MySQL 8.0Glottochronology
J
4

The easiest way in SQLAlchemy 1.4/2.0 with the new unified API:

from sqlalchemy import exists


session.scalar(
    exists()
    .where(User.email == '[email protected]')
    .select()
)
Jd answered 31/3, 2023 at 16:41 Comment(0)
E
-4

it can be done:

from sqlalchemy import select

user = session.scalars(
    select(User).where(User.email=="[email protected]")
).first()

if user:
    pass
else:
    pass
Elodiaelodie answered 1/4, 2022 at 2:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.