Respostas:
filter_by
é usado para consultas simples nos nomes das colunas usando kwargs regulares, como
db.users.filter_by(name='Joe')
O mesmo pode ser feito com o filter
não uso de kwargs, mas com o operador de igualdade '==', que foi sobrecarregado no objeto db.users.name:
db.users.filter(db.users.name=='Joe')
Você também pode escrever consultas mais poderosas usando filter
, como expressões como:
db.users.filter(or_(db.users.name=='Ryan', db.users.country=='England'))
type(model.column_name == 'asdf')
→sqlalchemy.sql.elements.BinaryExpression
.filter
. uma consulta como id=12345
, query(users).filter(id == id)
não será filtrada users.id
. Em vez disso, ele avaliará id == id
como True
e retornará todos os usuários. Você precisa usar .filter(users.id == id)
(como demonstrado acima). Eu cometi esse erro hoje cedo.
Na verdade, nós os fundimos originalmente, ou seja, havia um método semelhante ao "filtro" que aceitava *args
e **kwargs
, onde você podia passar uma expressão SQL ou argumentos de palavras-chave (ou ambos). Na verdade, acho isso muito mais conveniente, mas as pessoas sempre ficaram confusas com isso, pois geralmente ainda estão superando a diferença entre column == expression
e keyword = expression
. Então nós os separamos.
column == expression
vs. keyword = expression
é o ponto chave a ser feito sobre a diferença entre filter
e filter_by
. Obrigado!
filter_by
poderia ser um pouco mais rápido que filter
.
filter_by
é ser capaz de escrever apenas o nome do campo, para essa classe, sem perguntas - embora flter
exija o objeto da coluna real - que normalmente exige que você digite (e leia) pelo menos um nome de classe redundante. Portanto, se alguém deseja filtrar por igualdade, é bastante conveniente.
filter_by
usa argumentos de palavra-chave, enquanto que filter
permite argumentos de filtragem python comofilter(User.name=="john")
É um açúcar de sintaxe para uma gravação mais rápida de consultas. Sua implementação em pseudocódigo:
def filter_by(self, **kwargs):
return self.filter(sql.and_(**kwargs))
Para AND, você pode simplesmente escrever:
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'))
pode ser escrito como
session.query(db.users).filter((db.users.name=='Ryan') | (db.users.country=='England'))
Além disso, você pode obter objetos diretamente por PK através do get
método:
Users.query.get(123)
# And even by a composite PK
Users.query.get(123, 321)
Ao usar o get
caso, é importante que o objeto possa ser retornado sem a solicitação do banco de dados a partir da identity map
qual pode ser usado como cache (associado à transação)
users.filter
da resposta anterior. E pode ser que seja minha culpa :) O query
atributo é query_property e é um açúcar bastante comum hoje em dia
db.users.name=='Ryan'
avaliaria uma vez uma constante e depois não teria sentido a partir de então? Parece que seria necessário usar um lambda para que isso funcionasse.