Как исправить ошибку fetchall в Telegram боте на Python

    При разработке ботов на Python с библиотекой aiogram и aiosqlite новички часто сталкиваются с ошибкой AttributeError: 'Connection' object has no attribute 'fetchall'. Эта проблема возникает из-за неправильного порядка выполнения запроса к базе данных. В этой статье мы подробно разберём, как правильно выполнять SELECT-запросы и выводить найденные строки.

    Почему возникает ошибка fetchall?

    Ошибка AttributeError говорит о том, что у объекта Connection нет метода fetchall(). В библиотеке aiosqlite (и стандартном sqlite3) метод fetchall() принадлежит объекту Cursor, а не самому соединению. После вызова await db.execute() возвращается курсор, который и нужно использовать для получения данных.

    Правильный способ запроса к SQLite

    Чтобы избежать ошибки, нужно сохранить результат db.execute() в переменную-курсор, а затем вызвать у него fetchall(). Кроме того, важно правильно подставлять значение переменной message_name - использовать параметризованный запрос, а не просто строку в кавычках.

    Исправленный код:

    @start_router.message(Form.search_for_name)
    async def search_name(message: types.Message):
        message_name = message.text.strip()
        async with aiosqlite.connect('base.db') as db:
            cursor = await db.execute(
                'SELECT username, user_tg, name, soname FROM user WHERE [name] = ?',
                (message_name,)
            )
            users = await cursor.fetchall()
            if users:
                users_str = '\n'.join([str(user) for user in users])
                await message.answer(users_str)
            else:
                await message.answer('Совпадений не найдено.')
            await db.commit()

    Ключевые изменения:

    • cursor = await db.execute(...) - получаем курсор.
    • await cursor.fetchall() - вызываем метод у курсора.
    • WHERE [name] = ? - используем плейсхолдер ? и передаём значение кортежем (message_name,).
    • Добавлена проверка if users:, чтобы не отправлять пустой список.

    Дополнительные советы для работы с SQLite в aiogram

    При разработке ботов с базой данных важно учитывать несколько моментов:

    • Параметризация запросов - всегда используйте ? вместо конкатенации строк, чтобы избежать SQL-инъекций.
    • Асинхронность - все операции с aiosqlite должны быть с await.
    • Закрытие соединения - контекстный менеджер async with автоматически закроет соединение после выхода.
    • Обработка пустого результата - проверяйте, что fetchall() вернул хотя бы одну запись.

    Пример с форматированием вывода

    Чтобы данные выглядели читаемо, можно отформатировать каждую строку вручную:

    if users:
        lines = []
        for u in users:
            lines.append(f'Имя: {u[2]}, Фамилия: {u[3]}, Юзернейм: {u[0]}, ID: {u[1]}')
        await message.answer('\n'.join(lines))

    Этот подход делает ответ бота более информативным и удобным для пользователя.

    Заключение

    Ошибка fetchall у соединения - типичная ловушка для начинающих. Запомните: после await db.execute() обязательно используйте курсор для вызова fetchall(). Следуя нашим рекомендациям, вы сможете легко выводить нужные строки из базы данных в Telegram боте.

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