Ошибка AttributeError: 'Database' object has no attribute 'cursor' в Python

    При разработке Telegram-бота на Python с использованием SQLite вы можете столкнуться с ошибкой AttributeError: 'Database' object has no attribute 'cursor'. В этом материале мы подробно разберём причины её возникновения и предложим пошаговое решение.

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

    Ошибка возникает, когда вы пытаетесь обратиться к атрибуту cursor объекта класса Database, но этот атрибут не был определён или был переопределён. В вашем коде атрибут self.cursor создаётся внутри метода __init__, но в методе delete_queue вы используете self.connection.cursor, что корректно. Однако в методе add_queue вы вызываете self.cursor.execute, но если объект Database был создан без вызова __init__ или атрибут cursor был удалён, возникает эта ошибка.

    Основные причины проблемы

    • Неправильная инициализация объекта: Если вы не вызвали __init__ или он завершился с ошибкой, атрибут self.cursor не будет создан.
    • Опечатки в коде: Например, вы случайно переопределили self.cursor другим значением или удалили его.
    • Несоответствие версий Python или библиотек: Редко, но может влиять на работу атрибутов.

    Как исправить ошибку AttributeError cursor?

    1. Проверьте инициализацию класса Database

    Убедитесь, что конструктор __init__ выполняется без ошибок. В вашем примере он выглядит верно:

    class Database:
        def __init__(self, database_file):
            self.connection = sqlite3.connect(database_file, check_same_thread=False)
            self.cursor = self.connection.cursor()

    Проверьте, что файл базы данных существует и доступен для записи.

    2. Единообразно используйте cursor

    Рекомендуется всегда использовать self.connection.cursor() внутри каждого метода, чтобы избежать проблем с областью видимости. Исправленный код для add_queue:

    def add_queue(self, chat_id):
        with self.connection:
            cursor = self.connection.cursor()
            cursor.execute("INSERT INTO queue (chat_id) VALUES (?)", (chat_id,))

    Обратите внимание на запятую после (chat_id,) - это обязательный синтаксис для кортежа из одного элемента.

    3. Проверьте вызов метода в боте

    Убедитесь, что объект db создаётся до вызова db.add_queue. В вашем коде это так, но проверьте, не переопределяется ли db где-то ещё.

    Полный исправленный код для примера

    import sqlite3
    
    class Database:
        def __init__(self, database_file):
            self.connection = sqlite3.connect(database_file, check_same_thread=False)
        
        def add_queue(self, chat_id):
            with self.connection:
                cursor = self.connection.cursor()
                cursor.execute("INSERT INTO queue (chat_id) VALUES (?)", (chat_id,))
                self.connection.commit()
        
        def delete_queue(self, chat_id):
            with self.connection:
                cursor = self.connection.cursor()
                cursor.execute("DELETE FROM queue WHERE chat_id = ?", (chat_id,))
                self.connection.commit()

    Дополнительные советы по отладке

    • Добавьте print(dir(db)) перед вызовом add_queue, чтобы увидеть список атрибутов объекта.
    • Используйте try-except для обработки исключений и логирования.
    • Проверьте, что вы импортировали правильный класс Database из модуля database.

    Следуя этим рекомендациям, вы быстро устраните ошибку AttributeError: 'Database' object has no attribute 'cursor' и ваш Telegram-бот будет работать корректно.

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