Экранирование sql запроса python

Escape SQL «LIKE» для Postgres с помощью psycopg2

Имеет ли psycopg2 функцию для ускорения значения операнда LIKE для Postgres? Например, мне может понадобиться сопоставить строки, начинающиеся со строки «20% всех», поэтому я хочу написать что-то вроде этого:

sql = '. WHERE . LIKE %(myvalue)s' cursor.fetchall(sql,

Есть ли существующая функция escape_sql_like, которую я мог бы подключить сюда? (Аналогичный вопрос Явным образом цитирую строковое значение (Python DB API/Psycopg2), но я не смог найти ответ есть.)

7 ответов

Да, это настоящий беспорядок. Оба MySQL и PostgreSQL используют для этого по умолчанию обратную косую черту. Это ужасная боль, если вы снова избегаете строки с помощью обратных косых черт вместо использования параметризации, а также неверны в соответствии с ANSI SQL: 1992, в котором говорится, что по умолчанию нет лишних символов escape поверх нормального экранирования строки и следовательно, нет возможности включить литерал % или _ . Я бы предположил, что простой метод обратной косой черты также ошибочен, если вы отключите обратные слэши-экраны (которые сами не соответствуют ANSI SQL), используя NO_BACKSLASH_ESCAPE sql_mode в MySQL или standard_conforming_strings conf в PostgreSQL ( которые разработчики PostgreSQL угрожают сделать для нескольких версий сейчас). Единственное реальное решение — использовать малоизвестный синтаксис LIKE. ESCAPE для указания явного escape-символа для LIKE -pattern. Это используется вместо обратного слэша в MySQL и PostgreSQL, что делает их совместимыми с тем, что делают все остальные, и дает гарантированный способ включения внеполосных символов. Например, с знаком = в качестве escape:

# 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 (по модулю, который, конечно же, изменяется на разных модулях db). По-прежнему может возникнуть проблема с MS SQL Server/Sybase, которая, по-видимому, также допускает [a-z] -символьные группы символов в выражениях LIKE . В этом случае вы также захотите избежать символа [ с .replace(‘[‘, ‘=[‘) . Однако, согласно ANSI SQL, экранирование символов, которые не требуют экранирования, недействительно! (Argh!) Поэтому, хотя он, вероятно, все еще будет работать через настоящие СУБД, вы все равно не будете ANSI-совместимым. Вздох.

Читайте также:  Set constant in java

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

SELECT procpid, current_query FROM pg_stat_activity WHERE (CURRENT_TIMESTAMP - query_start) >= '%s minute'::interval AND current_query !~ '^autovacuum' ORDER BY (CURRENT_TIMESTAMP - query_start) DESC; 

Поскольку этот синтаксис запроса не использует ключевое слово «LIKE», вы можете делать то, что хотите. и не мутить воды по отношению к python и psycopg2.

Вы также можете взглянуть на эту проблему под другим углом. Что ты хочешь? Вам нужен запрос, который для любого строкового аргумента выполняет LIKE, добавляя «%» к аргументу. Хороший способ выразить это, не прибегая к функциям и расширениям psycopg2, может быть:

sql = ". WHERE . LIKE %(myvalue)s||'%'" cursor.execute(sql, < 'myvalue': '20% of all'>) 

Интересно, действительно ли все это необходимо. Я использую psycopg2 и просто могу использовать:

data_dict['like'] = psycopg2.Binary('%'+ match_string +'%') cursor.execute("SELECT * FROM some_table WHERE description ILIKE %(like)s;", data_dict) 

Источник

Python-сообщество

[RSS Feed]

  • Начало
  • » Python для новичков
  • » Экранирование смешанных кавычек для вставки в базу (mySQL)

#1 Март 5, 2014 13:19:10

Экранирование смешанных кавычек для вставки в базу (mySQL)

Добрый день всем! Заранее извиняюсь если было, но поиском ничего не нашел.
При составлении книжного каталога возникла такая проблема:
Есть произведение (на самом деле не одно, но возьмем это для примера) с названием:
“Четыре ночи мечтателя” (Quatre nuits d’un rêveur, 1971) Робера Брессона
Как видно в строке есть и одинарные и двойные кавычки.
Пробовал несколько способов для экранирования:
1. При помощи xss.quoteattr() (парные кавычки она вроде обрабатывает, а вот одинарные нет)
2. При помощи замены string.replace(b_name,“’”,“”“\’”“”) — здесь вообще срока никак не меняется
3. Сочетанием этих способов. и оборачиванием строки в разные кавычки, в зависимости от того какие кавычки есть в самой строке.

Google готовых ответов не дал

Как правильно поступать в таком случае, что бы можно было такую строку передать в параметре в строку SQL-запроса?
u»’INSERT INTO books (b_name) VALUES () «»’.format(name=b_name) (реальный запрос сложнее, тут просто сократил для ясности).

#2 Март 5, 2014 14:50:50

Экранирование смешанных кавычек для вставки в базу (mySQL)

В python апостроф и двойная кавычка экранируется так:

>>> string = '“Четыре ночи мечтателя” (Quatre nuits d\'un rêveur, 1971) Робера Брессона ' >>> string = string.replace('\'', ' ') >>> string = string.replace('\"', ' ') 

Отредактировано alexsis (Март 5, 2014 14:58:47)

#3 Март 5, 2014 15:16:00

Экранирование смешанных кавычек для вставки в базу (mySQL)

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

Источник

Экранирование кавычек для MySQL в python

Следуя совету в этой теме Я сохраняю свой list как string тип в MySQL database , но я сталкиваюсь с этой ошибкой:

_mysql_exceptions.ProgrammingError: (1064, 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near \'foo_bar" but I can\\\'t bar.\', u\'high\', 0]]")\' at line 1') 

В некоторых записях списка, как этот:

var1 = 'Name' var2 = 'Surname' var3 = 15 var4 = [u'The Meter', [[u'Black', u'foo foo bar bar "foo_bar" but I can\'t bar', u'high', 0]]] 

Я подумал, что это потому, что в начале foo_bar есть двойная кавычка, и я использую следующий код для записи в базу данных:

SQL = 'INSERT INTO test_table (col1, col2, col3, col4) VALUES ("<>", "<>", "<>", "<>")'.format(var1, var2, var3, var4) cursor.execute(SQL) 

И двойные кавычки не избежали. Если я удалю двойные кавычки из:
(«<>«, «<>«, «<>«, «<>«) , я получу ту же ошибку, Я попытался использовать другое форматирование строки ( %s ), но это тоже не сработало.
Любые идеи?

2 ответа

не используйте форматирование строк для интерполяции значений SQL. Используйте параметры SQL:

SQL = 'INSERT INTO test_table (col1, col2, col3, col4) VALUES (%s, %s, %s, %s)' cursor.execute(SQL, (var1, var2, var3, var4)) 

Здесь %s — параметры SQL; Затем база данных позаботится о том, чтобы экранировать значения (передаваемые в качестве 2-го аргумента для объекта cursor.execute).

Какой синтаксис вам нужно использовать, зависит от вашего адаптера базы данных; некоторые используют %s , другие используют ? для заполнителей.

В противном случае вы не можете использовать контейнеры Python, такие как список, для этих параметров. Вы должны сначала сериализовать это в формат строки; Вы можете использовать JSON для этого, но тогда вам также придется помнить, что при запросе базы данных нужно снова декодировать JSON в строку Python. Вот что пытались передать ответы на другой вопрос.

Например, если var4 это список, вы можете использовать:

cursor.execute(SQL, (var1, var2, var3, json.dumps(var4))) 
SQL = 'INSERT INTO test_table (col1, col2, col3, col4) VALUES ("", "", "", "")'.format(var1, var2, var3, str(var4)) cursor.execute(SQL) 

применяется ascii() и, следовательно, экранирует не-ASCII символы, такие как кавычки и даже смайлики.

Источник

Python-сообщество

[RSS Feed]

  • Начало
  • » Python для новичков
  • » Экранирование символов

#1 Март 24, 2020 06:29:59

Экранирование символов

Здравствуйте
Python 3.8.2, windows 10
Как можно обновить бд MySQL, если в переменной спецсимволы, т.е.
с такой переменной обновляется
data1=“11111”
cursor.execute(f“UPDATE `s` SET `p`= WHERE `id`=6”)
а вот с такой переменной выходит ошибка
data1=’ и т.д.’
PS: в PHP есть функция mysql_real_escape_string(), но в python(е), не могу найти подобную

#2 Март 24, 2020 06:49:26

Экранирование символов

data1=' и т.д.' cursor.execute("UPDATE `s` SET `p`=%s WHERE `id`=6", (data1,)) 

В документации к модулю pcycopg2 (библиотека доступа к БД Postgresql) есть такое место:

Warning
Never, never, NEVER use Python string concatenation (+) or string parameters interpolation (%) to pass variables to a SQL query string. Not even at gunpoint.

Предупреждение
Никогда, никогда, НИКОГДА не используйте конкатенацию строк Python (+) или интерполяцию строковых параметров (%) для передачи переменных в строку запроса SQL. Даже под дулом пистолета.

Отредактировано Striver (Март 24, 2020 06:52:41)

#3 Март 24, 2020 07:28:37

Экранирование символов

Спасибо за ответ, правда непонятно, где у меня конкатенация строки(+нигде нет), подставил вместо <> знак %, но это не решило проблему, наверное я не всё указал, у меня библиотека import pymysql.cursors

#4 Март 24, 2020 10:33:20

Экранирование символов

Неважно, какая у тебя библиотека, все библиотеки доступа к СУБД в Питоне действуют максимально похожим образом. Ты просто вообще не понял, что я тебе написал. Нельзя подставлять данные из переменных в SQL-строку. Их нужно отдельно применять внутри команды cursor.execute вторым параметром в виде кортежа из переменных.

Вот пример из документации к твоей библиотеке pymysql.cursors:

with connection.cursor() as cursor: # Create a new record sql = "INSERT INTO `users` (`email`, `password`) VALUES (%s, %s)" cursor.execute(sql, ('webmaster@python.org', 'very-secret')) 

Здесь значения ‘webmaster@python.org’ и ‘very-secret’ в SQL не вставляют, их отдельно добавляют при вызове cursor.execute.

Отредактировано Striver (Март 24, 2020 10:33:53)

Источник

Оцените статью