Filter и filter_by в SQLAlchemy: выбор и правильное использование
Пройдите тест, узнайте какой профессии подходите
Быстрый ответ
В SQLAlchemy filter
поддерживает использование сложных SQL-выражений и стандартные операции сравнения:
# "Возраст это лишь число... но большее 30" 😆
session.query(MyModel).filter(MyModel.age > 30)
В то же время filter_by
применяется для упрощённого использования ключевых аргументов, идеально подходя для проверки равенства:
# Похоже, Джону сегодня не в духе 🙃
session.query(MyModel).filter_by(age=30)
Используйте filter
для выполнения сложных и тонких запросов, а filter_by
– для простых и ясных.
Определяем ПРАВИЛЬНЫЙ выбор запроса
filter
позволяет вам применять сложные условия с использованием логического ИЛИ, манипулировать SQL-функциями и выполнить сложные операции, недоступные в filter_by
:
# Когда сложно выбрать, кто твой любимый пользователь... Эд или Венди 🤔
from sqlalchemy import or_
session.query(User).filter(or_(User.name == 'ed', User.name == 'wendy'))
filter_by
лежит во значении за своим простым и лаконичным синтаксисом для запросов, которые требуют только проверки на равенство и не включают сложных SQL-выражений:
# Поищем всех тридцатилетних Джонов. Это распространенное имя. 🤷
session.query(MyModel).filter_by(age=30, name='John')
Получаем преимущество с помощью гибкости filter
filter
является решением для динамически меняющихся запросов. Он незаменим при построении запросов, основанных на различных условиях:
# В поисках идеального запроса 🧐
query = session.query(MyModel)
if condition1:
query = query.filter(MyModel.age > 30)
if condition2:
query = query.filter(MyModel.name.startswith('A'))
results = query.all()
filter_by
не обладает такой гибкостью, поскольку предполагает использование только статически определённых ключевых аргументов.
ЛУЧШЕЕ из двух миров: Объединение filter и filter_by
Мы можем использовать в одном запросе filter
и filter_by
, объединяя их преимущества:
# Filter – это левое полушарие, filter_by – правое. Вместе они образуют 'идеальный мозг запроса'!
from sqlalchemy import or_
session.query(MyModel).filter_by(name='John').filter(or_(MyModel.age > 20, MyModel.education == 'PhD'))
Максимально эффективное получение объектов: использование get
Для ускорения работы используйте get
для получения объектов по первичному ключу. Он использует карту идентичности сессии и может вернуть объект без выполнения запроса, если он уже присутствует в данной карте:
# Чемпион по скорости среди ORM? Конечно, '.get()'
my_model = session.query(MyModel).get(primary_key)
Карта идентичности также способствует эффективному использованию кэширования в filter_by
, если результаты запросов уже были сохранены в сессии.
Визуализация
Представьте, что вы в библиотеке и ищете книгу по названию:
filter
можно сравнить с запросом к библиотекарю найти все книги, в названии которых есть "Advanced". Это предполагает индивидуальный поиск.
📚➡️👓: ["Advanced Cooking", "Advanced Python"] ➡️ Индивидуальный поиск
В то время как filter_by
похож на выбор книги на полке, где метка точно соответствует "Advanced Python", обеспечивая прямой и упрощённый поиск.
📚🏷️👓: "Advanced Python" ➡️ Ярлык книги на полке
Основное различие: filter
обеспечивает гибкость и сложность, тогда как filter_by
обозначает простоту и строгость.
Повышаем уровень с использованием OR в filter
Создание условий с ОР проще с использованием filter
. Можно применять побитовый оператор ОР |
или функцию or_()
из модуля sqlalchemy
:
# Эд или кто-то младше пяти лет. Какова же будет эта компания? 🤣
from sqlalchemy import or_
session.query(User).filter(or_(User.name == 'ed', User.age < 5))
И вариант с побитовым ОР:
session.query(User).filter((User.name == 'ed') | (User.age < 5))
Битва синтаксисов: filter против filter_by
Разбор синтаксических отличий важен для выбора оптимального способа формулировки запроса:
filter
: применяется для выражений видастолбец == выражение
session.query(MyModel).filter(MyModel.age == 30)
filter_by
: использует ключевые аргументы, равные определенному значению
# Как бы говоришь: "Алекса, найди модель с возрастом 30 лет". 🗣️🎙️
session.query(MyModel).filter_by(age=30)
Выбирайте синтаксис, который помогает формировать более эффективные и грамотные запросы.
Полезные материалы
- Документация SQLAlchemy 2.0 – Здесь вы узнаете больше о методе
filter
. - Руководство по объектно-реляционному отображению (API 1.x) – Ценный источник информации о работе с Query API в SQLAlchemy 1.4 / 2.0.
- GitHub – sqlalchemy/sqlalchemy – Исходный код
filter
иfilter_by
. - SQLAlchemy — pysheeet – Удобная шпаргалка по запросам в SQLAlchemy, включая
filter
,filter_by
и другое. - Документация SQLAlchemy 2.0 – Информация о API метода
filter_by
.