Здесь есть несколько проблем.
- Вы не можете использовать заполнитель для имени столбца. Его можно использовать только для выражений, и заменой будет буквальное значение, полученное из списка параметров. Если у вас есть переменное имя столбца, вам нужно использовать обычное форматирование строки; у вас должен быть белый список для предотвращения внедрения SQL.
- Заполнители не заменяются внутри кавычек.
- Ваши значения вложены слишком глубоко. Второй аргумент
c.execute()
должен быть повторяемым, и каждый элемент заполняется одним заполнителем. search
- это список кортежа, а затем вы помещаете его в другой кортеж, когда пишете (search,)
. Таким образом, значения вложены на 2 уровня в глубину, а не в аргументе кортежа. - Значения функции по умолчанию не должны быть вызовами
input()
. Значения по умолчанию оцениваются при определении функции, а не при ее вызове. Таким образом, при загрузке скрипта у вас будут запрашиваться входные данные, и при каждом вызове функции будут использоваться те же значения по умолчанию. - Вы вызываете
c.fetchall()
перед выполнением запроса. - Вам не хватает
for item in items:
l oop. conn.commit()
не требуется после SELECT
запросов, только запросы, которые изменяют базу данных. И вы не должны вызывать conn.close()
в этой функции, так как она не открывала соединение; другие функции могут все еще использовать соединение.
def get_info(search_by=None, value=None):
valid_search_by = ['col1', 'col2', 'col3']
if search_by is None:
search_by = input("Search by: ")
if search_by not in valid_search_by:
raise ValueErr("Invalid search_by")
if value is None:
value = input("Value: ")
c.execute(f"SELECT * FROM credentials WHERE {search_by} LIKE ?", (value,))
items = c.fetchall()
for item in items:
print(f"{item[0]}", f"{item[1]}", f"{item[2]}", f"{item[3]}")
Кроме того, нет необходимости использовать str()
в f-строке, поскольку форматирование автоматически преобразует значения в строки.