Как правильно добавлять данные пользователя в базу данных Telegram-бота на Python
При разработке ботов на Python с библиотекой aiogram и aiosqlite начинающие разработчики часто сталкиваются с ситуацией, когда программа не выдаёт ошибок, но данные не сохраняются. Рассмотрим типичные причины и способы их устранения.
Почему данные не записываются в таблицу
Основная проблема в вашем коде - неправильный синтаксис SQL-запроса. В SQLite строковые значения должны быть заключены в одинарные кавычки, а не в двойные. Кроме того, использование форматирования строк через %s делает код уязвимым для SQL-инъекций. Рекомендуется использовать параметризованные запросы.
Правильный способ вставки данных
Замените строку await db.execute('INSERT OR IGNORE INTO user (name) VALUES("%s")' % (user_name)) на параметризованный вариант:
await db.execute('INSERT OR IGNORE INTO user (name) VALUES (?)', (user_name,))Символ ? является placeholder, а кортеж (user_name,) передаёт значение безопасно. Это исключает ошибки с кавычками и защищает от взлома.
Проверка структуры таблицы
Убедитесь, что таблица user существует в файле base.db и содержит столбец name. Если таблица не создана, добавьте код создания при запуске бота:
async with aiosqlite.connect('base.db') as db:
await db.execute('''CREATE TABLE IF NOT EXISTS user (id INTEGER PRIMARY KEY, name TEXT UNIQUE)''')
await db.commit()Обратите внимание на UNIQUE - если вы используете INSERT OR IGNORE, повторные попытки вставить одинаковое имя будут игнорироваться без ошибок.
Проверка работы хендлера в aiogram
Убедитесь, что хендлер @start_router.message(Form.name) действительно срабатывает. Добавьте отладочный вывод:
@start_router.message(Form.name)
async def add_name(message: types.Message):
user_name = message.text.strip()
print(f'Получено имя: {user_name}')
async with aiosqlite.connect('base.db') as db:
await db.execute('INSERT OR IGNORE INTO user (name) VALUES (?)', (user_name,))
await db.commit()
await message.answer('Готово')Если в консоли появляется имя, значит хендлер активен. Если нет - проверьте регистрацию Form и состояние.
Использование транзакций и commit
Вы уже используете await db.commit(), что правильно. Однако в некоторых версиях aiosqlite может потребоваться явное закрытие соединения. Используйте контекстный менеджер async with, как в вашем коде - это гарантирует корректное завершение.
Советы по отладке
- Проверьте, что файл
base.dbсоздаётся в той же папке, откуда запускается скрипт. - Откройте базу в SQLite Browser и посмотрите, есть ли записи.
- Убедитесь, что Form.name - это экземпляр
State, а не просто строка.
После исправления синтаксиса и внедрения параметризации данные начнут сохраняться корректно. Если проблема остаётся - проверьте права на запись в директорию и версии библиотек.