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 == idjako Truei 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 *argsi **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 == expressioni keyword = expression. Więc podzieliliśmy je.
column == expressionkontra keyword = expressionjest kluczową kwestią do rozróżnienia między filteri filter_by. Dzięki!
filter_bymoże być trochę szybsze niż filter.
filter_byto, aby móc napisać jutro nazwę pola, dla tej klasy, bez zadawania pytań - podczas gdy flterwymaga 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_byużywa argumentów słów kluczowych, natomiast filterpozwala 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 getmetodą:
Users.query.get(123)
# And even by a composite PK
Users.query.get(123, 321)
W getprzypadku użycia przypadku ważne jest, aby obiekt mógł zostać zwrócony bez żądania bazy danych, z identity mapktórego można go wykorzystać jako pamięć podręczną (powiązaną z transakcją)
users.filterz poprzedniej odpowiedzi. I może to być moja wina :) queryatrybut 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.