Задать вопрос
@AirronBark

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

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

С недавнего времени пришлось перейти с 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()

Код бота:
@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} !\n\nВыберите пункт меню.',
            reply_markup=nav.main_choise)
  • Вопрос задан
  • 975 просмотров
Подписаться 2 Простой 3 комментария
Решения вопроса 1
SoreMix
@SoreMix Куратор тега Python
yellow
Данные не возвращаются в вашу переменную. Они лежат в курсоре.

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
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Vindicar
@Vindicar
RTFM!
Я полагаю, есть два способа сигнализации о пустом ответе, и разные движки используют разные подходы.
Либо БД может вернуть объект-курсор, который не содержит ни одной строки.
Либо БД может вернуть None.

Для понятности такая аналогия: пусть нам возвращают список. Если нам всегда возвращают список, то можем писать код так:
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)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы