Примечание: я немного переформатировал текстовые строки для удобства чтения, разделив строки.
Вы не интерполируете значения переменных в строку запроса. Следующая строка
conn.execute(
"INSERT INTO my_boardgames "
"(game_name,genre,recage,playtime,players) "
"VALUES "
"(val_game_name,val_genre,val_rec_age,val_play_time,val_players)");
Необходимо заменить на
conn.execute(
"INSERT INTO my_boardgames "
"(game_name,genre,recage,playtime,players) "
"VALUES "
"(?, ?, ?, ?, ?)",
(val_game_name, val_genre, val_rec_age, val_play_time, val_players));
Дополнительная информация
Как вы упомянули в комментариях, что выначинающий программист, я добавлю больше информации
В следующем коде будут использоваться только два столбца, чтобы сделать строки более короткими и удобочитаемыми.
AНаивный подход
Наиболее очевидным (но неэффективным, подверженным ошибкам и небезопасным) решением будет следующее:
conn.execute(
"INSERT INTO my_boardgames "
"(game_name, genre) "
"VALUES ('" + val_game_name + "', '" + val_genre + "')")
Конкатенация строк затрудняет чтение кода, и вам необходимоиметь дело с правильной ценовой цитатой самостоятельно, что легко ошибиться. Он также очень хрупкий и небезопасный, поскольку определенные значения могут привести к тому, что запрос станет недействительным, или (если он создан злонамеренно) может заставить запрос сделать что-то совершенно другое ( Атака SQL-инъекции ( видео * 1031)*)).
Улучшение читаемости с помощью форматирования строк
Второй подход может привести к следующему, что сделает код более читабельным.
# Using traditional "printf-style" formatting
conn.execute(
"INSERT INTO my_boardgames "
"(game_name, genre) "
"VALUES ('%s', '%s')" % (val_game_name , val_genre))
# Using "new-style" formatting
conn.execute(
"INSERT INTO my_boardgames "
"(game_name, genre) "
"VALUES ('{}', '{}')".format(val_game_name , val_genre))
# Using f-strings
conn.execute(
"INSERT INTO my_boardgames "
"(game_name, genre) "
f"VALUES ('{val_game_name}', '{val_genre}')")
Эти 3 версиивсе технически одно и то же решение. Они заменяют специальные заполнители внутри строки перед тем, как отправит ее в библиотеку базы данных (в данном случае SQLite). Результирующая строка запроса SQL такая же, как и строка, использующая +
для объединения строк. Код становится немного более читабельным, но код все еще хрупок и небезопасен по той же причине, что и первый вариант.
Правильный способ сделать это
Это приводит нас к финальномуРешение (в моем первоначальном ответе выше):
# Using "new-style" formatting
conn.execute(
"INSERT INTO my_boardgames "
"(game_name, genre) "
"VALUES (?, ?)", (val_game_name , val_genre))
Есть некоторые тонкие, но важные различия:
- Мы отправляем два значения в
execute()
функция: Строка запроса с вопросительными знаками (заполнителями) и значениями, которые должны использоваться для этих заполнителей (все предыдущие методы отправляли только одно значение: строку SQL, которую мы вручную создали со значениями). - Мы не заменяем знаки вопроса сами. Мы разрешаем библиотеке БД разобраться с этим
- Нам не нужно беспокоиться о цитировании (обратите внимание, что вокруг вопросительных знаков нет кавычек).
Это делает код читабельными, что самое главное, прост в обслуживании.
Разрешение библиотеке БД работать с заполнителями позволяет БД решать, как правильно заключать в кавычки значения, что уменьшает вышеупомянутую атаку SQL-Injection.