- Escape SQL «LIKE» для Postgres с помощью psycopg2
- 7 ответов
- Python-сообщество
- #1 Март 5, 2014 13:19:10
- Экранирование смешанных кавычек для вставки в базу (mySQL)
- #2 Март 5, 2014 14:50:50
- Экранирование смешанных кавычек для вставки в базу (mySQL)
- #3 Март 5, 2014 15:16:00
- Экранирование смешанных кавычек для вставки в базу (mySQL)
- Экранирование кавычек для MySQL в python
- 2 ответа
- Python-сообщество
- #1 Март 24, 2020 06:29:59
- Экранирование символов
- #2 Март 24, 2020 06:49:26
- Экранирование символов
- #3 Март 24, 2020 07:28:37
- Экранирование символов
- #4 Март 24, 2020 10:33:20
- Экранирование символов
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-совместимым. Вздох.
Вместо того, чтобы избегать символа процента, вместо этого вы можете использовать реализацию регулярного выражения 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-сообщество
- Начало
- » 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-сообщество
- Начало
- » 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)