Почему PostdgreSQL постоянно выдает ошибку AttributeError: 'NoneType' object has no attribute 'fetchall'?

Ссылка скопирована
1 ответ

Здравствуйте!

С недавнего времени пришлось перейти с SQLite на PostdgreSQL
что ж при адаптировании кода к библиотеке psycorg2 выдает ошибку ко всем атрибутам fetchall() во всех функциях :
return result.fetchall()
AttributeError: 'NoneType' object has no attribute 'fetchall'

Да, дата база пустая, но у меня стоит условие, если она нет id - пропускай дальше, то есть в sqlite все это работало, сейчас же я просто мб ошибаюсь в синтаксисе. Прошу помочь советом)

Дальше мой код обращения к дб:

def __init__(self, database_file):         """Подключаемся к Базе Данных и сохраняем курсор соединения"""         self.connection = psycopg2.connect(user="user", password="pass", host="localhost", port="5432", database=database_file)         #self.connection = sqlite3.connect(database_file)         self.connection.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)         self.cursor = self.connection.cursor()      def client_exists(self, user_id):         """Проверяем есть ли клиент уже в базе данных"""         result = self.cursor.execute("""SELECT * FROM clients WHERE user_id = %s""", (user_id,))         return bool(len(result.fetchall()))      def get_new_logo(self):         """Получаем картинку"""         result = self.cursor.execute("""SELECT logo FROM logotype WHERE id = 1""")         return result.fetchall()

def __init__(self, database_file): """Подключаемся к Базе Данных и сохраняем курсор соединения""" self.connection = psycopg2.connect(user="user", password="pass", host="localhost", port="5432", database=database_file) #self.connection = sqlite3.connect(database_file) self.connection.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT) self.cursor = self.connection.cursor() def client_exists(self, user_id): """Проверяем есть ли клиент уже в базе данных""" result = self.cursor.execute("""SELECT * FROM clients WHERE user_id = %s""", (user_id,)) return bool(len(result.fetchall())) def get_new_logo(self): """Получаем картинку""" result = self.cursor.execute("""SELECT logo FROM logotype WHERE id = 1""") return result.fetchall()

Код бота:

@dp.message_handler(commands=("start", "Начать")) @dp.message_handler(Text(equals=('начать', 'start'), ignore_case=True)) async def start(message: types.Message):     logo = db.get_new_logo()     for r in logo:         if r[0] == 1:             await message.answer_photo(r[2])      if (not db.client_exists(message.from_user.id)):         await message.answer(             text=f'Добро пожаловать, Что ж, начнем сотрудничество?',reply_markup=nav.start_menu)     else:         await message.answer(             text=f'C возвращением , {message.from_user.first_name} !nnВыберите пункт меню.',             reply_markup=nav.main_choise)

@dp.message_handler(commands=("start", "Начать")) @dp.message_handler(Text(equals=('начать', 'start'), ignore_case=True)) async def start(message: types.Message): logo = db.get_new_logo() for r in logo: if r[0] == 1: await message.answer_photo(r[2]) if (not db.client_exists(message.from_user.id)): await message.answer( text=f'Добро пожаловать, Что ж, начнем сотрудничество?',reply_markup=nav.start_menu) else: await message.answer( text=f'C возвращением , {message.from_user.first_name} !nnВыберите пункт меню.', reply_markup=nav.main_choise)

Дополнительно:

Это ошибка не СУБД. Чтобы убедиться в этом - посмотрите постгресовский лог.

  • Ошибка в коде, не в PostgreSQL
    Смотрите на какую строку ругается при ошибке, почему атрибут NoneType, возможно будет иметь атрибут fath
  • inworkl, я тут понимаю что он выводит напрямую к logo, больше я в ошибке не вижу ссылок. При этом до этого все работало с sqlite, я основной код не менял
    File "D:Phyton35thParallelBothandlersusersgreates.py", line 29, in start
    logo = db.get_new_logo()
    File "D:Phyton35thParallelBotdb_connect.py", line 162, in get_new_logo
    return result.fetchall()
    AttributeError: 'NoneType' object has no attribute 'fetchall'
  • Данные не возвращаются в вашу переменную. Они лежат в курсоре.

    def client_exists(self, user_id):         """Проверяем есть ли клиент уже в базе данных"""         self.cursor.execute("""SELECT * FROM clients WHERE user_id = %s""", (user_id,))         return bool(len(self.cursor.fetchall()))

    def client_exists(self, user_id): """Проверяем есть ли клиент уже в базе данных""" self.cursor.execute("""SELECT * FROM clients WHERE user_id = %s""", (user_id,)) return bool(len(self.cursor.fetchall()))

    И можно сделать немного вот так (если не путаю):

    def client_exists(self, user_id):         """Проверяем есть ли клиент уже в базе данных"""         self.cursor.execute("""SELECT * FROM clients WHERE user_id = %s""", (user_id,))         return self.cursor.fetchone() is not None

    def client_exists(self, user_id): """Проверяем есть ли клиент уже в базе данных""" self.cursor.execute("""SELECT * FROM clients WHERE user_id = %s""", (user_id,)) return self.cursor.fetchone() is not None

    • Ага, я привык к sqlite3 что там все через connection, тоже уже тоже методом тыка понял self.cursor. fetchone() работает, спасибо:)

    Ответы:

    Я полагаю, есть два способа сигнализации о пустом ответе, и разные движки используют разные подходы.
    Либо БД может вернуть объект-курсор, который не содержит ни одной строки.
    Либо БД может вернуть None.

    Для понятности такая аналогия: пусть нам возвращают список. Если нам всегда возвращают список, то можем писать код так:

    for line in db.query("..."):     do_something(line)

    for line in db.query("..."): do_something(line)

    Сработает даже еслди в ответе нет ни одной строки, т.е. на пустом списке.
    А вот если нам при пустом ответе возвращают None, то код выше вылетит с ошибкой NoneType is not iterable, и надо будет переписать так:

    result = db.query("...") if result is not None:     for line in result:         do_something(line)

    result = db.query("...") if result is not None: for line in result: do_something(line)

    • Хорошее решение, тоже пробовал что-то подобное, но к сожалению ни Ваше, ни мое не помогло, ошибку все равно он выдает связанную с result.fetchall() :(
    Нужно решить такую задачу?

    Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

    Заказать помощь
    Лучший ответ
    1
    Ольга Сеть Ответ

    Ошибка AttributeError: 'NoneType' object has no attribute 'fetchall' обычно возникает, когда метод fetchall вызывается на объекте, который равен None. Это означает, что запрос к базе данных не вернул никаких результатов, и вместо списка результатов вернулся объект None.

    Чтобы избежать этой ошибки, необходимо проверить результат выполнения запроса к базе данных перед вызовом метода fetchall. В примере ниже показано, как это можно сделать в Python с использованием библиотеки psycopg2 для работы с PostgreSQL:

    ```python
    import psycopg2

    # устанавливаем соединение с базой данных
    conn = psycopg2.connect("dbname=test user=postgres password=secret")

    # создаем курсор для выполнения запросов
    cur = conn.cursor()

    # выполняем SQL запрос
    cur.execute("SELECT * FROM table_name")

    # получаем результат выполнения запроса
    result = cur.fetchone()

    # проверяем, что результат не равен None
    if result is not None:
    # если результат не равен None, то можно вызывать метод fetchall
    rows = cur.fetchall()
    for row in rows:
    print(row)
    else:
    print("Результат пустой")

    # закрываем курсор и соединение
    cur.close()
    conn.close()
    ```

    В этом примере мы сначала вызываем метод fetchone, чтобы получить одну строку результата. Затем мы проверяем, что результат не равен None, и только после этого вызываем метод fetchall для получения всех оставшихся строк результата.

    Таким образом, следует всегда проверять результат выполнения запроса к базе данных на равенство None перед вызовом метода fetchall, чтобы избежать ошибки AttributeError.

    Другие ответы (0)

    Пока нет других ответов. Будьте первым, кто поможет автору.

    Ответить на вопрос

    комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *

    Вам также может быть интересно