A
A
AirronBark2021-11-19 18:11:14
Python
AirronBark, 2021-11-19 18:11:14

Why does PostdgreSQL keep throwing AttributeError: 'NoneType' object has no attribute 'fetchall'?

Hello!

Recently, I had to switch from SQLite to PostdgreSQL,
so when adapting the code to the psycorg2 library, it gives an error to all fetchall() attributes in all functions :
return result.fetchall()
AttributeError: 'NoneType' object has no attribute 'fetchall'

Yes, date the base is empty, but I have a condition, if it does not have an id - skip further, that is, it all worked in sqlite, now I'm just mistaken in the syntax. Please help with advice)

Then my code for accessing the db:

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()

Bot code:
@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)

Answer the question

In order to leave comments, you need to log in

2 answer(s)
S
soremix, 2021-11-19
@AirronBark

No data is returned to your variable. They are in the cursor.

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

And you can do a little like this (if I'm not confused):
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

V
Vindicar, 2021-11-19
@Vindicar

I guess there are two ways to signal an empty response, and different engines take different approaches.
Or the database may return a cursor object that does not contain a single row.
Or the database can return None.
For clarity, such an analogy: let us return a list. If we are always returned a list, then we can write the code like this:

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

It will work even if there is not a single line in the answer, i.e. on an empty list.
But if None is returned to us with an empty response, then the code above will crash with the error NoneType is not iterable, and it will be necessary to rewrite it like this:
result = db.query("...")
if result is not None:
    for line in result:
        do_something(line)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question