Есть ли способ динамического построения sql-запроса

#python #sqlite

Вопрос:

Я кодирую менеджер баз данных на Python с помощью SQLite3 и tkinter и пытаюсь построить функцию запроса. Каждый элемент в моей базе данных имеет несколько атрибутов: «имя», «путь», «видно», «качество», «франшиза», «жанр» и «теги».

Если возможно, я хочу, чтобы пользователь мог выбрать определенные параметры в графическом интерфейсе, а затем создать запрос к базе данных, но проблема в том, что пользователь должен иметь возможность выбрать любой или все эти атрибуты для фильтрации или включения в запрос. Например, один запрос может запрашивать все объекты в базе данных с именем «Тони», франшизой «История игрушек» и жанром «Действие», в то время как другой запрос может просто требовать, чтобы все объекты видели «да».

У меня было много проблем с этим, и, хотя у меня было искушение, я не могу жестко закодировать каждую перестановку частей инструкции SQL Select, и я чувствую, что в любом случае есть лучший способ, которого я не вижу. Я попытался установить «оператор по умолчанию»: SELECT * FROM objects WHERE а затем добавить к нему «нравится genre IS ? » и «если это имеет значение AND franchise IS ? «, но затем я сталкиваюсь с проблемой, что я не знаю, как динамически форматировать замены. Я почти уверен, что это можно сделать, так что буду рад любой помощи. Спасибо!

Комментарии:

1. использовать jinja.palletsprojects.com/en/3.0.x/templates/# для правильного построения динамических запросов не рекомендуется использовать объединение строк

2. @gold_cy почему объединение строк — плохая идея?

3. лучше позволить хорошо протестированной библиотеке обрабатывать форматирование

Ответ №1:

Вы абсолютно на правильном пути. Подумайте о составлении списка предложений WHERE и параллельного списка замен. В этом примере я использую строки, но вы поняли идею:

 subs = []
where = []
where.append( "name = ?" )
subs.append( "Tony" )
where.append( "franchise = ?" )
subs.append( "Toy Story" )

sql = "SELECT * FROM movies WHERE "   (" AND ".join(where))   ";"
query = cursor.execute( sql, subs )
 

Комментарии:

1. Вы заставляете это казаться таким простым, ха-ха, хотя почему к операторам where добавлены точки с запятой? это необходимо?