web-dev-qa-db-fra.com

Quelle est la différence entre filter et filter_by dans SQLAlchemy?

Quelqu'un pourrait-il expliquer la différence entre les fonctions filter et filter_by dans SQLAlchemy? Je suis confus et je ne vois pas vraiment la différence. Lequel devrais-je utiliser?

267
bodacydo

filter_by est utilisé pour les requêtes simples sur les noms de colonnes utilisant des kwargs classiques, comme

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

La même chose peut être accomplie avec filter, sans utiliser kwargs, mais en utilisant l'opérateur d'égalité '==', surchargé sur l'objet db.users.name:

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

Vous pouvez également écrire des requêtes plus puissantes en utilisant filter, telles que des expressions telles que:

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

337
Daniel Velkov

En réalité, nous avions initialement fusionné ces éléments, c’est-à-dire qu’il existait une méthode de type "filtre" qui acceptait * args et ** kwargs, dans laquelle vous pouviez passer une expression SQL ou des arguments de mots clés (ou les deux). En fait, je trouve cela beaucoup plus pratique, mais les gens étaient toujours déconcertés, car ils surmontaient généralement la différence entre column == expression et keyword = expression. Nous les avons donc séparés.

109
zzzeek

filter_by utilise des arguments de mots clés, tandis que filter autorise les arguments de filtrage Pythonic tels que filter(User.name=="john")

34
Johannes Charra

C'est un sucre de syntaxe pour écrire des requêtes plus rapidement. Son implémentation en pseudocode:

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

Pour ET vous pouvez simplement écrire:

session.query(db.users).filter_by(name='Joe', surname='Dodson')

en fait

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

peut être écrit comme

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

Aussi, vous pouvez obtenir un objet directement par PK via la méthode get:

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

Lorsque vous utilisez get case, il est important que l'objet puisse être renvoyé sans demande de base de données de identity map pouvant être utilisé en tant que cache (associé à une transaction).

29
enomad