Requête Flask-SQLAlchemy insensible à la casse

96

J'utilise Flask-SQLAlchemy pour interroger une base de données d'utilisateurs; cependant, tandis que

user = models.User.query.filter_by(username="ganye").first()

reviendra

<User u'ganye'>

Faire

user = models.User.query.filter_by(username="GANYE").first()

Retour

None

Je me demande s'il existe un moyen d'interroger la base de données d'une manière insensible à la casse, de sorte que le deuxième exemple revienne toujours

<User u'ganye'>
Ganye
la source

Réponses:

193

Vous pouvez le faire en utilisant les fonctions lowerou upperde votre filtre:

from sqlalchemy import func
user = models.User.query.filter(func.lower(User.username) == func.lower("GaNyE")).first()

Une autre option consiste à effectuer une recherche en utilisant ilikeau lieu de like:

.query.filter(Model.column.ilike("ganye"))
plaes
la source
3
Cela rendrait-il la requête plus lente par rapport à la filter_byméthode où la colonne du nom d'utilisateur est indexée?
CaptainDaVinci
13

En améliorant la réponse de @ plaes, celle-ci raccourcira la requête si vous ne spécifiez que la ou les colonnes dont vous avez besoin:

user = models.User.query.with_entities(models.User.username).\
filter(models.User.username.ilike("%ganye%")).all()

L'exemple ci-dessus est très utile au cas où l'on aurait besoin d'utiliser jsonify de Flask à des fins AJAX, puis dans votre javascript, y accéder en utilisant data.result :

from flask import jsonify
jsonify(result=user)
iChux
la source
@ VedranŠego J'ai vu le lien, merci pour la référence. J'effectuerai également mon propre test.
iChux
3

tu peux faire

user = db.session.query(User).filter_by(func.lower(User.username)==func.lower("GANYE")).first()

Ou vous pouvez utiliser la fonction ilike

 user = db.session.query(User).filter_by(User.username.ilike("%ganye%")).first()
Mohammad Aarif
la source
La deuxième option ne devrait pas avoir de pourcentages
axwell