Python SQLite ищет заголовок сообщения с несколькими ключевыми словами

#python #sql #sqlite

#python #sql #sqlite

Вопрос:

У меня возникли некоторые проблемы с написанием этого на python, и, похоже, я не могу решить эту проблему, кроме использования форматирования строк (что настоятельно не рекомендуется)

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

Например, если пользователь ввел «python SQL mysql», мне нужно найти все сообщения, которые соответствуют хотя бы одному из ключевых слов. В этом примере запрос будет

 SELECT posts.title FROM posts 
    WHERE lower(posts.title) LIKE "%python%" OR 
    lower(posts.title) LIKE "%sql%" OR 
    lower(posts.title) LIKE "%mysql%";
  

Однако вот в чем проблема. Количество ключевых слов может варьироваться. Поэтому я не могу написать фиксированный оператор SQL, например

 db.execute("SELECT posts.title FROM posts WHERE posts.title LIKE ? OR posts.title LIKE ?",("%" keyword1 "%", "%" keyword2 "%"))
  

Вместо этого мне приходится прибегать к циклу for в Python, что-то вроде:

 query = "posts.title LIKE '%"   keywords[0]   "%'"
keywords.remove(0)
for k in keywords:
    query  = "OR posts.title LIKE '%"   k  "'%"
  

Однако это, очевидно, не рекомендуется. Хотя то, над чем я работаю, является школьным проектом, поэтому он не является критически важным, плюс мы не оцениваемся по атакам SQL-инъекций, я хочу знать, как правильно решить этот вопрос.

Ответ №1:

Я думаю, что сначала подумал о, возможно, неоптимальных, но более безопасных методах, создайте оператор запроса, но не добавляйте в них userInput:

 query = "posts.title Like ? "
for i in range(len(keywords) - 1):
    query  = "OR posts.title Like ?"

query = "SELECT posts.title FROM posts WHERE "   query
  

И затем я использую sqlite API, сделай это за меня:

 keywords = list()
for k in keywords:
    keywords.append("%"   k   "%")
keywords = tuple(keywords)
result = db.execute(query, keywords)