Odpowiedzi:
filter_by
służy do prostych zapytań o nazwy kolumn przy użyciu zwykłych kwargs, takich jak
db.users.filter_by(name='Joe')
To samo można osiągnąć filter
, nie używając kwargs, ale zamiast tego używając operatora równości „==”, który został przeciążony na obiekcie db.users.name:
db.users.filter(db.users.name=='Joe')
Możesz także pisać bardziej rozbudowane zapytania filter
, takie jak wyrażenia takie jak:
db.users.filter(or_(db.users.name=='Ryan', db.users.country=='England'))
type(model.column_name == 'asdf')
→sqlalchemy.sql.elements.BinaryExpression
.filter
. zapytanie jak id=12345
, query(users).filter(id == id)
nie będzie filtrować users.id
. Zamiast tego oceni id == id
jako True
i zwróci wszystkich użytkowników. Musisz użyć .filter(users.id == id)
(jak pokazano powyżej). Dzisiaj popełniłem ten błąd.
Tak naprawdę pierwotnie je scaliliśmy, tzn. Istniała metoda podobna do „filtru”, która zaakceptowała *args
i **kwargs
, gdzie można było przekazać wyrażenie SQL lub argumenty słowa kluczowego (lub oba). Uważam, że jest to o wiele wygodniejsze, ale ludzie zawsze byli tym zdezorientowani, ponieważ zwykle wciąż przekraczają różnicę między column == expression
i keyword = expression
. Więc podzieliliśmy je.
column == expression
kontra keyword = expression
jest kluczową kwestią do rozróżnienia między filter
i filter_by
. Dzięki!
filter_by
może być trochę szybsze niż filter
.
filter_by
to, aby móc napisać jutro nazwę pola, dla tej klasy, bez zadawania pytań - podczas gdy flter
wymaga rzeczywistego obiektu kolumny - który zwykle wymaga wpisania (i odczytania) przynajmniej nadmiarowej nazwy klasy. Więc jeśli ktoś chce filtrować według równości, jest to raczej wygodne.
filter_by
używa argumentów słów kluczowych, natomiast filter
pozwala na filtrowanie argumentów pythonicznych, takich jakfilter(User.name=="john")
Jest to cukier składniowy do szybszego pisania zapytań. Jego implementacja w pseudokodzie:
def filter_by(self, **kwargs):
return self.filter(sql.and_(**kwargs))
Dla AND możesz po prostu napisać:
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'))
można zapisać jako
session.query(db.users).filter((db.users.name=='Ryan') | (db.users.country=='England'))
Możesz także uzyskać obiekt bezpośrednio przez PK get
metodą:
Users.query.get(123)
# And even by a composite PK
Users.query.get(123, 321)
W get
przypadku użycia przypadku ważne jest, aby obiekt mógł zostać zwrócony bez żądania bazy danych, z identity map
którego można go wykorzystać jako pamięć podręczną (powiązaną z transakcją)
users.filter
z poprzedniej odpowiedzi. I może to być moja wina :) query
atrybut jest zapytanie_property i jest to obecnie dość standardowy cukier
db.users.name=='Ryan'
oceniałby raz na stały, a następnie byłby bez znaczenia odtąd? Wydaje się, że aby to zadziałało, trzeba by użyć lambda.