sqlalchemy существует для запроса

Как проверить, существуют ли данные в запросе?

Например:

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

Как я могу проверить, существуют ли пользователи с этим адресом электронной почты?

Я могу проверить это с

users_query.count()

но как это проверить с помощью exists?


person lestat    schedule 04.10.2011    source источник


Ответы (4)


Следующее решение немного проще:

from sqlalchemy.sql import exists

print session.query(exists().where(User.email == '...')).scalar()
person Cito    schedule 11.11.2012
comment
Обратите внимание, что это дало бы неправильные результаты для полиморфных типов. При фильтрации как по родительскому, так и по дочернему атрибуту результирующий запрос будет выбирать из декартова произведения (внешнего соединения) таблиц. Чтобы исправить это, вы должны вручную установить пункт FROM через select_from: e = exists(select([1]).select_from(User).where(and_(User.email == '...', ...))).select() - person aikoven; 17.08.2016
comment
@aikoven: ваше предложение приводит к ошибке Every derived table must have its own alias. Добавление exists(…).select().alias('foo') исправило это (см. alias()< /а> функция). - person Jens; 05.01.2018

Самый приемлемый и читаемый вариант для меня это

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

как

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

который возвращает True или False.

person Eugene Kovalev    schedule 31.01.2017
comment
Также обратите внимание, что некоторые базы данных, такие как SQL Server, не допускают присутствия выражения EXISTS в предложении столбцов оператора SELECT. Чтобы выбрать простое логическое значение на основе существования как WHERE, используйте sqlalchemy.literal: session.query(literal(True)).filter(q.exists()).scalar() - person kaka; 12.07.2017
comment
Это вызывает следующее исключение: AttributeError: type object 'User' has no attribute 'query' - person Fusion; 26.09.2019
comment
Атрибут .query специфичен для Flask-SQLAlchemy. Вы бы использовали session.query(session.query(User).filter(User.id == 1).exists()).scalar(). - person Martijn Pieters; 15.09.2020

Я не знаю, как это сделать с помощью orm query api. Но вы можете перейти на уровень ниже и использовать exists из 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()
person Gary van der Merwe    schedule 04.10.2011

Для SQL Server мне пришлось сделать следующее:

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 = '...')

Но без 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 = '...'
person MarredCheese    schedule 03.10.2019
comment
То же самое для Oracle 12c. Спасибо за решение - person Moritz Ringler; 31.01.2020
comment
session.query(cls).filter_by(**kwargs).first() is not None также будет работать без импорта literal, по крайней мере, для MySQL 8.0. - person Elder Druid; 08.07.2021