Ответы:
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'оценили бы один раз как константу, а потом были бы бессмысленными с тех пор? Кажется, что для этого нужно использовать лямбду.