Risposte:
filter_by
è usato per semplici query sui nomi delle colonne usando normali kwarg, come
db.users.filter_by(name='Joe')
Lo stesso può essere realizzato con filter
, non usando kwargs, ma usando invece l'operatore di uguaglianza '==', che è stato sovraccaricato sull'oggetto db.users.name:
db.users.filter(db.users.name=='Joe')
Puoi anche scrivere query più potenti utilizzando filter
, come espressioni come:
db.users.filter(or_(db.users.name=='Ryan', db.users.country=='England'))
type(model.column_name == 'asdf')
→sqlalchemy.sql.elements.BinaryExpression
.filter
. una query come id=12345
, query(users).filter(id == id)
non filtra users.id
. Invece, valuterà id == id
come True
e restituirà tutti gli utenti. Devi usare .filter(users.id == id)
(come mostrato sopra). Oggi ho fatto questo errore.
In realtà li abbiamo uniti insieme in origine, ovvero esisteva un metodo simile a "filtro" che accettava *args
e **kwargs
, in cui si potevano passare espressioni SQL o argomenti di parole chiave (o entrambi). In realtà lo trovo molto più conveniente, ma le persone ne sono sempre state confuse, dal momento che di solito continuano a superare la differenza tra column == expression
e keyword = expression
. Quindi li abbiamo divisi.
column == expression
vs. keyword = expression
sia il punto chiave da fare sulla differenza tra filter
e filter_by
. Grazie!
filter_by
potrebbe essere un po 'più veloce di filter
.
filter_by
è di poter scrivere solo il nome del campo, per quella classe, senza fare domande - mentre flter
richiede l'oggetto colonna reale - che di solito richiederà uno per digitare (e leggere) almeno un nome di classe ridondante. Quindi, se si vuole filtrare per uguaglianza, è piuttosto conveniente.
filter_by
usa argomenti di parole chiave, mentre filter
consente argomenti di filtro pythonic comefilter(User.name=="john")
È uno zucchero sintattico per una scrittura più veloce delle query. La sua implementazione in pseudocodice:
def filter_by(self, **kwargs):
return self.filter(sql.and_(**kwargs))
Per AND puoi semplicemente scrivere:
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'))
può essere scritto come
session.query(db.users).filter((db.users.name=='Ryan') | (db.users.country=='England'))
Inoltre puoi ottenere l'oggetto direttamente tramite PK tramite il get
metodo:
Users.query.get(123)
# And even by a composite PK
Users.query.get(123, 321)
Quando si utilizza get
case è importante che l'oggetto possa essere restituito senza la richiesta del database da identity map
cui può essere usato come cache (associato alla transazione)
users.filter
dalla risposta precedente. E potrebbe essere colpa mia :) l' query
attributo è query_property ed è abbastanza uno zucchero standard al giorno d'oggi
db.users.name=='Ryan'
valuteresti una volta una costante e da allora in poi non avrebbe più senso? Sembra che uno dovrebbe usare un lambda per farlo funzionare.