Фильтр набора запросов Django charfield без экранирования подстановочного знака MYSQL - PullRequest
2 голосов
/ 29 декабря 2011

Я ищу способ сделать это:

qs = MyModel.objects.filter(mystring__like="____10____")

#Which would create a sql clause
... LIKE '____10____'

вместо того, чтобы вести себя так:

qs = MyModel.objects.filter(mystring__icontains="____10____")
#Which creates a sql clause
... LIKE %\_\\_\\_\\_10\\_\\_\\_\\_%

Я знаю, что могу использовать фильтр регулярных выражений, но это значительно медленнее и более подвержено ошибкам, чем просто использование встроенной функции подстановочных знаков mysql (я проверял это непосредственно в mysql, строки запросов достаточно длинные, чтобы разница была существенная).


EDIT: разобрался, как это сделать с помощью метода .extra () с помощью madisvain.

qs = MyModel.objects.extra(where=["`mystring` LIKE '____10____'"])

С точки зрения разницы в производительности, 2000 случайных запросов с использованием регулярных выражений заняли 20,5 секунд, при этом 2000 случайных запросов занимают 6 секунд.

Ответы [ 3 ]

1 голос
/ 29 декабря 2011

Я даже не знал, что у django была эта __-подобная версия.Ну, но в соответствии с документами, пожалуйста, прочтите это!https://docs.djangoproject.com/en/dev/topics/db/queries/#escaping-percent-signs-and-underscores-in-like-statements

Вы должны писать запрос следующим образом.

    qs = MyModel.objects.filter(mystring__contains="____10____")

Или вот так.

    qs = MyModel.objects.extra(where="mystring LIKE '____10____'")

Подробнее о методе extra () читайте здесь: https://docs.djangoproject.com/en/dev/ref/models/querysets/#extra

1 голос
/ 29 декабря 2011

Вы можете использовать менеджер raw() для предварительной обработки необработанных SQL-запросов, поэтому строка будет иметь вид:

qs = MyModel.objects.raw("SELECT * from MyApp_MyModel where mystring like %s", [variable])
0 голосов
/ 04 марта 2014

Я бы предложил функцию фильтра регулярных выражений или регистр не учитывается версия iregex . Пример:

qs = MyModel.objects.filter(mystring__regex="....10....")

Недостаток: вы можете проверить поддержку регулярных выражений для используемого вами бэкэнда, повлиять на производительность, а в случае изменения бэкенда это может вызвать потенциальные проблемы: синтаксис регулярного выражения соответствует используемому бэкэнду базы данных .

...