Какая разница между фильтром и filter_by в SQLAlchemy?

Может ли кто-нибудь объяснить разницу между функциями filter и filter_by в SQLAlchemy? Я смущен и не могу видеть разницу. Какой я должен использовать?

Ответ 1

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

Ответ 2

Мы фактически объединили их изначально, то есть был метод "фильтра" -like, который принимал *args и **kwargs, где вы могли передавать выражение SQL или аргументы ключевого слова (или оба). Я на самом деле считаю, что это намного удобнее, но люди всегда были смущены этим, поскольку они обычно все еще преодолевают разницу между column == expression и keyword = expression. Таким образом, мы разделили их.

Ответ 3

filter_by использует аргументы ключевого слова, тогда как filter допускает аргументы фильтрации pythonic, такие как filter(User.name=="john")

Ответ 4

Это синтаксический сахар для более быстрого написания запросов. Его реализация в псевдокоде:

def filter_by(self, **kwargs):
    return self.filter(sql.and_(**kwargs))

Для И вы можете просто написать:

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

Также вы можете получить объект напрямую с помощью PK методом get:

Users.query.get(123)
# And even by a composite PK
Users.query.get(123, 321)

При использовании кейса get важно, чтобы объект можно было возвращать без запроса к базе данных из identity map, который можно использовать как кеш (связанный с транзакцией)

Ответ 5

разница между filter() и filter_by() заключается в том, что первая (filter()) работает как оператор or (||), а filter_by() работает как оператор and (&&). filter() оценивает значение true, если любой из предоставленных аргументов True. Он сравнивает его с значком ==. Пока filter_by() оценивает True тогда и только тогда, когда все предоставленные аргументы оцениваются до True. Поэтому следует проявлять осторожность при вызове каждой функции, так как они не оценивают свои аргументы одинаково. Оформить заказ в этом примере ниже:

borrowedlist = Borrowedbooks.query.filter_by(bookid = bookid, userid = userid, status = 'false').first()
        if borrowedlist == None:
            return None
        return borrowedlist

возвращает True тогда и только тогда, когда все приведенные аргументы возвращают True в то время как:

borrowedlist = Borrowedbooks.query.filter(bookid == bookid, userid == userid, status == 'false').first()
        if borrowedlist == None:
            return None
        return borrowedlist

будет возвращать True, если любой из представленных аргументов оценивает True