#python #mysql #python-3.x #sql-injection #pymysql
#python #mysql #python-3.x #sql-инъекция #pymysql
Вопрос:
Прошу прощения за плохое название, но я часами искал в Интернете, но ничего не смог найти.
Подумайте о пользовательском поиске, выполняемом с текстом «это хорошо». Я хочу разделить текст пробелами и выполнить SQL-запрос с несколькими «или… например, «зависит от количества слов. Их может быть несколько. Я пробовал;
sub_query ""
search = "this is good"
split_by_space = search.split(" ")
for word in split_by_space:
sub_query = sub_query "content like '%{}%' or".format(word) #---> THIS IS NOT ESCAPED
sub_query = sub_query[0:-3] #---> to remove last ' or'
cursor.execute("select content from posts where %s",(sub_query))
Это неправильный способ предотвращения SQL-инъекции или подготовленного оператора.
Итак, как сделать подготовленный оператор в Python / pymysql, если я хочу разделить слова пробелами и выполнить поиск по каждому отдельному слову?
Комментарии:
1. Это, вероятно, одно из лучших руководств по предотвращению внедрения SQL. realpython.com/prevent-python-sql-injection
2. Такие инструменты, как конструктор запросов SQLAlchemy (который можно использовать полностью независимо от ORM в том же пакете), сделают это за вас автоматически (динамически генерируя запрос с заполнителями и внеполосный набор значений для этих заполнителей). Я бы посоветовал не изобретать велосипед, тем более что драйверы баз данных для DB-API Python могут использовать один из нескольких интерфейсов, поэтому для обеспечения совместимости требуется поддержка всех доступных соглашений; SQLAlchemy уже поддерживает весь набор, поэтому его использование значительно упрощает переключение с MySQL на PostgreSQL / Oracle / что угодно.
Ответ №1:
Вот один из способов сделать это безопасно:
search = "this is good"
split_by_space = search.split(" ")
terms = []
params = []
for word in split_by_space:
terms.append("content like %s")
params.append("%%{}%%".format(word))
query = "select content from posts where %s".format(" OR ".join(terms))
cursor.execute(query, params)
Но вы обнаружите, что использование LIKE
с подстановочными знаками не работает должным образом. Использование LIKE
может привести к тому, что запрос займет в тысячи раз больше времени, чем использование полнотекстового индекса (в зависимости от количества строк в таблице). Смотрите Мою презентацию с полнотекстовым поиском.