Да, это настоящий бардак. И MySQL, и PostgreSQL по умолчанию используют для этого обратную косую черту. Это ужасная боль, если вы также снова экранируете строку с помощью обратной косой черты вместо использования параметризации, и это также неверно в соответствии с ANSI SQL: 1992, в котором говорится, что по умолчанию нет дополнительных escape-символов поверх обычного экранирования строки, и следовательно, нет возможности включить литерал %
или _
.
Я предполагаю, что простой метод замены обратной косой черты также пойдет не так, если вы отключите экранирование обратной косой черты (которые сами по себе несовместимы с ANSI SQL), используя NO_BACKSLASH_ESCAPE
sql_mode в MySQL или standard_conforming_strings
conf в PostgreSQL (которым разработчики PostgreSQL угрожали сделать для пары версий сейчас).
Единственным реальным решением является использование малоизвестного синтаксиса LIKE...ESCAPE
для явного указания управляющего символа для шаблона LIKE
. Это используется вместо обратной косой черты в MySQL и PostgreSQL, что делает их соответствующими тому, что делают все остальные, и дает гарантированный способ включения внеполосных символов. Например, со знаком =
в качестве побега:
# look for term anywhere within title
term= term.replace('=', '==').replace('%', '=%').replace('_', '=_')
sql= "SELECT * FROM things WHERE description LIKE %(like)s ESCAPE '='"
cursor.execute(sql, dict(like= '%'+term+'%'))
Это работает с базами данных, совместимыми с PostgreSQL, MySQL и ANSI SQL (конечно, по модулю paramstyle, который меняется в разных модулях db).
Все еще может быть проблема с MS SQL Server/Sybase, который, по-видимому, также допускает группы символов в стиле [a-z]
в выражениях LIKE
. В этом случае вы также захотите экранировать буквальный символ [
с помощью .replace('[', '=[')
. Однако, согласно ANSI SQL, экранирование символа, который не требует экранирования, недопустимо! (Аргх!) Таким образом, хотя он, вероятно, по-прежнему будет работать в реальных СУБД, вы все равно не будете соответствовать стандарту ANSI. вздох...
person
bobince
schedule
21.01.2010