2010-01-24 15 views

Respuesta

229

filter_by se utiliza para consultas simples en los nombres de columna utilizando kwargs regulares, como

db.users.filter_by(name='Joe')

Lo mismo se puede lograr con filter, no usar kwargs, pero en lugar de utilizar el operador '==' igualdad , que ha sido sobrecargado en el objeto db.users.name:

db.users.filter(db.users.name=='Joe')

también puede escribir consultas más potentes utilizando filter, tales como expresiones como:

db.users.filter(or_(db.users.name=='Ryan', db.users.country=='England'))

+16

¿Cómo funciona esto bajo el capó? ¿No 'db.users.name ==' Ryan'' evaluar una vez a una constante y luego no tener sentido a partir de ese momento? Parece que uno necesitaría usar una lambda para que esto funcione. –

+30

el operador de igualdad está sobrecargado –

+2

'type (model.column_name == 'asdf')' → 'sqlalchemy.sql.elements.BinaryExpression' –

29

filter_by utiliza argumentos de palabra clave, mientras que filter permite que los argumentos de filtrado Pythonic como filter(User.name=="john")

93

De hecho, tuvimos estos fusionado en un principio, es decir, no era un "filtro" -como método que acepta * args y ** kwargs, donde puede pasar una expresión SQL o argumentos de palabra clave (o ambos). En realidad, creo que es mucho más conveniente, pero las personas siempre estaban confundidas, ya que por lo general siguen superando la diferencia entre column == expression y keyword = expression. Entonces los separamos.

+23

Creo que su punto sobre' column == expression' contra 'keyword = expression' es el punto clave para hacer acerca de la diferencia entre 'filter' y' filter_by'. ¡Gracias! – Hollister

+0

Esta es una buena pregunta relacionada: [http://stackoverflow.com/questions/19506105/flask-sqlalchemy-query-with-keyword-as-variable]. – Soferio

+2

Soy nuevo en sqlalchemy, así que disculpe si esta es una pregunta estúpida, pero filter_by() no parece permitir incluso las condiciones más simples, como "precio> = 100". Entonces, ¿por qué la función filter_by() funciona de todos modos, si solo puedes usarla para la condición más simple como "price = 100"? – PawelRoman

23

Es un azote de sintaxis para una escritura de consulta más rápida. Su implementación en pseudocódigo:

def filter_by(self, **kwargs): 
    return self.filter(sql.and_(**kwargs)) 

Para Y simplemente hay que escribir:

Users.query.filter_by(name='Joe', surname='Dodson') 

por cierto

db.users.filter(or_(db.users.name=='Ryan', db.users.country=='England')) 

se puede escribir como

db.users.filter((db.users.name=='Ryan') | (db.users.country=='England')) 

También se puede obtener el objeto directamente por PK vía get método:

Users.query.get(123) 
# And even by a composite PK 
Users.query.get(123, 321) 

Al utilizar get caso es importante que objeto puede ser devuelto sin solicitud de base de datos de identity map que puede ser utilizado como caché (asociada con la transacción)

+0

Estos ejemplos de código son engañosos: las instancias y las clases de tabla base declarativa no tienen métodos de filtro ni de consulta; ellos usan la sesión –

+0

Reproduzco 'users.filter' de la respuesta anterior. Y puede ser mi culpa :) el atributo 'query' es [query_property] (http://docs.sqlalchemy.org/en/latest/orm/contextual.html?highlight=query_property#sqlalchemy.orm.scoping.scoped_session. query_property) y es un azúcar bastante estándar hoy en día – enomad

-4

la diferencia entre filter() y filter_by() es que la former (filter()) funciona como una declaración or (||) y filter_by() funciona como una declaración and (&&). filter() evalúa verdadero si alguno de los argumentos proporcionados es True. Lo compara con el signo igual a ==. Mientras que filter_by() evalúa True si y solo si todos los argumentos proporcionados se evalúan como True. Por lo tanto, se debe tener cuidado al llamar a cada función, ya que no evalúan sus argumentos de la misma manera. Pedido este ejemplo a continuación:

borrowedlist = Borrowedbooks.query.filter_by(bookid = bookid, userid = userid, status = 'false').first() 
     if borrowedlist == None: 
      return None 
     return borrowedlist 

volvería True si y sólo si todos los argumentos proporcionados devuelve True mientras:

borrowedlist = Borrowedbooks.query.filter(bookid == bookid, userid == userid, status == 'false').first() 
     if borrowedlist == None: 
      return None 
     return borrowedlist 

volvería True si alguno de los argumentos proporcionados evalúa True

+3

Esto es completamente falso. Tanto 'filter' como' filter_by' unen múltiples argumentos con 'and_'. Consulte [la documentación del filtro] (http://docs.sqlalchemy.org/en/rel_1_1/orm/query.html#sqlalchemy.orm.query.Query.filter) –

Cuestiones relacionadas