Ошибка sqlite3.OperationalError: no such column в Disnake ModalInteraction
При разработке Discord-ботов на библиотеке Disnake с использованием SQLite часто возникает ошибка sqlite3.OperationalError: no such column. Она связана с неправильной подстановкой переменных в SQL-запрос. Разберём причины и правильные методы вставки данных.
Почему возникает ошибка no such column?
В исходном коде значения из модального окна подставляются напрямую в строку SQL через f-строку:
c.execute(f"INSERT INTO user VALUES ({inter.author.id}, {name}, {age}, {about})")SQLite интерпретирует текстовые значения как имена столбцов, если они не обёрнуты в кавычки. Например, если пользователь ввёл dfgeb, база данных ищет столбец с таким именем, а не значение.
Как правильно вставлять данные в SQLite?
Используйте параметризованные запросы (плейсхолдеры ? или :название). Это решит проблему и защитит от SQL-инъекций.
Пример с вопросительными знаками
async def callback(self, inter: disnake.ModalInteraction):
name = inter.text_values['name']
age = inter.text_values['age']
about = inter.text_values['about']
c.execute("INSERT INTO user VALUES (?, ?, ?, ?)", (inter.author.id, name, age, about))
conn.commit()Пример с именованными параметрами
c.execute("INSERT INTO user VALUES (:id, :name, :age, :about)",
{'id': inter.author.id, 'name': name, 'age': age, 'about': about})Дополнительные рекомендации
- Всегда используйте параметризованные запросы для любых данных от пользователя.
- Проверяйте типы данных:
ageлучше преобразовать вintчерезint(age). - Если таблица уже создана, убедитесь, что количество столбцов в
INSERTсоответствует схеме.
Почему это важно для безопасности?
Прямая подстановка значений открывает возможность SQL-инъекций. Злоумышленник может ввести в поле name что-то вроде '; DROP TABLE user; --, что удалит таблицу. Параметризация экранирует спецсимволы и гарантирует, что данные останутся данными.
Исправление ошибки no such column сводится к замене f-строки на плейсхолдеры. Это сделает код стабильнее и безопаснее.