Відповіді:
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))
Для І ви можете просто написати:
session.query(db.users).filter_by(name='Joe', surname='Dodson')
btw
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метод:
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'оцінювали б один раз постійним і потім з того часу були безглуздими? Здається, що для цього потрібно використовувати лямбда.