2016-04-20 5 views

Antwort

4

Der Kontext ist wichtig.

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

Hier gibt es keine Saite mit einer lower Methode zu nennen; Sie erstellen einen SQL-Befehl zum Ausführen in der Datenbank. func.lower gibt keine Zeichenfolge in Kleinbuchstaben zurück; Es gibt ein Objekt zurück, das SQL-Code darstellt, mit dem eine Zeichenfolge in Kleinbuchstaben erzeugt werden kann.


Wie mgilson weist darauf hin, gibt es keine Notwendigkeit func.lower auf tatsächlichen Python-Werte zu verwenden; Sie sind für jede Zeile, für die der Filter angewendet wird, konstant, aber ich bin nicht sicher, ob SQLAlchemy solche Situationen erkennen und optimieren kann. Entweder der folgenden

user = models.User.query.filter(func.lower(User.username) == "ganye").first() 
user = models.User.query.filter(func.lower(User.username) == "GaNyE".lower()).first() 

würde SQL-Code wie lower(username) = :lower_1 produzieren statt lower(username) = lower(:lower_1), die die SQL-Abfrage effizienter durch den Wegfall eines Anrufs zu lower für jede Zeile machen.

+0

Die zweite 'func.lower (' GaNyE ') 'kauft dich wahrscheinlich nicht viel über'' ganye'' oder '' GaNyE'.lower() ', oder? Es scheint mir, dass es nur als eine Operation auf der Spalte nützlich wäre ... – mgilson

+1

Richtig. Konstanten werden in Bindeparameter umgewandelt, so dass Sie mit 'low (: 1)' anstelle von '(: 1)' enden. Ich weiß nicht, ob SQLAlchemy erkennen kann, dass derselbe Wert immer an "lower" übergeben wird und den resultierenden Code optimiert, daher wäre es besser, in diesem Fall zuerst die Zeichenkette in Python klein zu schreiben. – chepner