Ответы:
filter_by
используется для простых запросов к именам столбцов с использованием обычных kwargs, например
db.users.filter_by(name='Joe')
То же самое можно сделать filter
, не используя kwargs, а вместо этого используя оператор равенства '==', который был перегружен в объекте db.users.name:
db.users.filter(db.users.name=='Joe')
Вы также можете написать более мощный запрос, используя filter
такие выражения, как:
db.users.filter(or_(db.users.name=='Ryan', db.users.country=='England'))
type(model.column_name == 'asdf')
→sqlalchemy.sql.elements.BinaryExpression
.filter
. запрос, как id=12345
, query(users).filter(id == id)
не будет фильтровать users.id
. Вместо этого, он будет оценивать , id == id
как True
и вернуть все пользователь. Вы должны использовать .filter(users.id == id)
(как показано выше). Я сделал эту ошибку сегодня утром.
Мы фактически объединили их изначально, то есть был метод, похожий на «фильтр», который принимал *args
и **kwargs
, где вы могли передать выражение SQL или аргументы ключевого слова (или оба). Я на самом деле считаю, что это намного удобнее, но люди всегда были смущены этим, так как они обычно все еще преодолевают разницу между column == expression
и keyword = expression
. Таким образом, мы разделили их.
column == expression
против» keyword = expression
- это ключевой момент, который необходимо учитывать в отношении разницы между filter
и filter_by
. Спасибо!
filter_by
может быть немного быстрее, чем filter
.
filter_by
заключается в том, чтобы иметь возможность написать просто имя поля, для этого класса, без вопросов - хотя flter
требуется фактический объект столбца - который обычно требует, чтобы он набрал (и прочитал) хотя бы избыточное имя класса. Итак, если кто-то хочет отфильтровать по равенству, это довольно удобно.
filter_by
использует аргументы ключевых слов, тогда как filter
разрешает питонную фильтрацию аргументов, таких какfilter(User.name=="john")
Это синтаксический сахар для более быстрого написания запросов. Его реализация в псевдокоде:
def filter_by(self, **kwargs):
return self.filter(sql.and_(**kwargs))
Для AND вы можете просто написать:
session.query(db.users).filter_by(name='Joe', surname='Dodson')
кстати
session.query(db.users).filter(or_(db.users.name=='Ryan', db.users.country=='England'))
можно записать как
session.query(db.users).filter((db.users.name=='Ryan') | (db.users.country=='England'))
Также вы можете получить объект напрямую с помощью get
метода PK :
Users.query.get(123)
# And even by a composite PK
Users.query.get(123, 321)
При использовании get
регистра важно, чтобы объект можно было возвращать без запроса к базе данных, из identity map
которого можно использовать кеш (связанный с транзакцией).
users.filter
из предыдущего ответа. И, может быть, это моя вина :) query
Атрибут query_property и его довольно стандартный сахар в наши дни
db.users.name=='Ryan'
оценили бы один раз как константу, а потом были бы бессмысленными с тех пор? Кажется, что для этого нужно использовать лямбду.