2016-04-20 2 views
2

Посмотрите на этот ответ: Case Insensitive Flask-SQLAlchemy QueryЗачем использовать sqlAlchemy func.lower (mystring) vs. mystring.lower()?

Почему лучше использовать SQLAlchemy-х func.lower(mystring) вместо питона родной mystring.lower()?

+0

Это, вероятно, мало чем отличается от строкового литерала, но имеет значение то, что вы можете использовать его в столбце: 'func.lower (SomeModel.some_column)' – mgilson

ответ

4

Контекст важен.

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

Здесь нет строки с помощью метода lower для вызова; вы составляете команду SQL для выполнения в базе данных. func.lower не возвращает строчную строку; он возвращает объект, представляющий код SQL, который может использоваться для создания строчной строки.


Как mgilson указывает, что нет необходимости использовать func.lower фактических значений Python; они являются постоянными для каждой строки, к которой применяется фильтр, но я не уверен, что SQLAlchemy может обнаруживать и оптимизировать такие ситуации. В любом из следующих

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

будет производить код SQL, как lower(username) = :lower_1 вместо lower(username) = lower(:lower_1), который может сделать SQL запрос более эффективным за счет устранения вызова lower для каждой линии.

+0

Второй 'func.lower (' GaNyE ') ', вероятно, не покупает вас намного выше' 'ganye'' или' 'GaNyE'.lower()', не так ли? Мне кажется, что это было бы полезно только в качестве операции над столбцом ... – mgilson

+1

Справа. Константы преобразуются в параметры привязки, поэтому вы заканчиваете 'lower (: 1)' вместо '(: 1)'. Я не знаю, сможет ли SQLAlchemy распознать, что одно и то же значение всегда передается в 'lower' и оптимизирует полученный код, поэтому лучше было бы вначале записать строку в Python в этом случае. – chepner

Смежные вопросы