Как правильно добавлять данные пользователя в базу данных 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, а не просто строка.

    После исправления синтаксиса и внедрения параметризации данные начнут сохраняться корректно. Если проблема остаётся - проверьте права на запись в директорию и версии библиотек.

    Часто задаваемые вопросы