Изменить запрос в соответствии с выбором пользователя в sqlite python

#python #sqlite

Вопрос:

У меня есть база данных sqlite с именем StudentDB, которая содержит 3 столбца: Номер, имя, Отметки. Теперь я хочу получить только те столбцы, которые пользователь выбирает в среде IDE. Пользователь может выбрать один или два столбца или все три. Как я могу соответствующим образом изменить запрос с помощью Python?

Я пытался:

 import sqlite3

sel={"Roll Number":12}

query = 'select * from StudentDB Where({seq})'.format(seq=','.join(['?']*len(sel))),[i for k,i in sel.items()]
con = sqlite3.connect(database)
cur = con.cursor()
cur.execute(query)

all_data = cur.fetchall()
all_data
 

Я получаю:

 operation parameter must be str
 

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

1. Одно важное дополнение как к вашему коду, так и к ответам на данный момент — обязательно положительно подтвердите, что ключи sel ожидаемых имен столбцов, с чем-то вроде VALID_COLUMNS = {'Name', 'Roll number'}; assert sel.keys() <= VALID_COLUMNS ; в противном случае у вас огромная дыра в безопасности

2. @sabik: это зависит от того, откуда берутся имена столбцов. Это абсолютно необходимо, если они где-то прочитаны, но бесполезно, если они просто жестко закодированы в приложении. И последнее является довольно распространенным вариантом использования…

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

Ответ №1:

Вы должны контролировать текст запроса. Предложение where всегда должно быть в форме WHERE colname=value [AND colname2=...] или (лучше) WHERE colname=? [AND ...] , если вы хотите построить параметризованный запрос.

Итак, вы хотите:

 query = 'select * from StudentDB Where '   ' AND '.join('"{}"=?'.format(col)
                                                        for col in sel.keys())
...
cur.execute(query, tuple(sel.values()))
 

Ответ №2:

В вашем коде query вместо этого теперь кортеж str , и именно поэтому возникла ошибка.

Я предполагаю, что вы хотите выполнить запрос, как показано ниже —

 select * from StudentDB Where "Roll number"=?
 

Затем вы можете изменить sql-запрос следующим образом (при условии, что вы хотите и, а не или) —

 query = "select * from StudentDB Where {seq}".format(seq=" and ".join('"{}"=?'.format(k) for k in sel.keys()))
 

и выполните запрос следующим образом —

 cur.execute(query, tuple(sel.values()))
 

Пожалуйста, убедитесь, что в вашем коде предоставленное database определено и содержит имя базы данных и studentDB действительно является именем таблицы, а не именем базы данных.