Відповіді:
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'
оцінювали б один раз постійним і потім з того часу були безглуздими? Здається, що для цього потрібно використовувати лямбда.