@Maxwell012

Как использовать asyncpg с aiogram?

У меня проблема с бд которая написанная на asyncpg внутри aiogram. Код бд:
class DataBase:

    def __init__(self):
        self.db_pool = None
        loop = asyncio.get_event_loop()
        loop.run_until_complete(self.create_pool())

    async def create_pool(self):
        try:
            self.db_pool = await asyncpg.create_pool(Config.POSTGRES_URI)
            async with self.db_pool.acquire() as connection:
                await connection.execute('SELECT 1')
            print("\tSuccessful connection to the database")
        except Exception as e:
            print(f"\tDatabase connection error: {e}")

Код запускается, и пишет что соединение установлено, но при первом запросе я получаю ошибку:
Cause exception while process update id=56403182 by bot id=6663434503
InterfaceError: cannot perform operation: another operation is in progress
Traceback (most recent call last):
  File "beauty_experts_bot/src/services/sql.py", line 27, in add_user
    await connection.execute("""INSERT INTO user (id, username, name) VALUES (?, ?, ?)""",
  File "beauty_experts_bot/venv/lib64/python3.11/site-packages/asyncpg/connection.py", line 319, in execute
    _, status, _ = await self._execute(
                   ^^^^^^^^^^^^^^^^^^^^
  File "beauty_experts_bot/venv/lib64/python3.11/site-packages/asyncpg/connection.py", line 1659, in _execute
    result, _ = await self.__execute(
                ^^^^^^^^^^^^^^^^^^^^^
  File "beauty_experts_bot/venv/lib64/python3.11/site-packages/asyncpg/connection.py", line 1684, in __execute
    return await self._do_execute(
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "beauty_experts_bot/venv/lib64/python3.11/site-packages/asyncpg/connection.py", line 1711, in _do_execute
    stmt = await self._get_statement(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "beauty_experts_bot/venv/lib64/python3.11/site-packages/asyncpg/connection.py", line 397, in _get_statement
    statement = await self._protocol.prepare(
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "asyncpg/protocol/protocol.pyx", line 168, in prepare
RuntimeError: Task <Task pending name='Task-29' coro=<Dispatcher._process_update() running at /home/davyd/MY_DATA/programming/tmp_project/beauty_experts_bot/venv/lib/python3.11/site-packages/aiogram/dispatcher/dispatcher.py:308>> got Future <Future pending cb=[Protocol._on_waiter_completed()]> attached to a different loop

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "beauty_experts_bot/venv/lib/python3.11/site-packages/aiogram/dispatcher/dispatcher.py", line 308, in _process_update
    response = await self.feed_update(bot, update, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "beauty_experts_bot/venv/lib/python3.11/site-packages/aiogram/dispatcher/dispatcher.py", line 157, in feed_update
    response = await self.update.wrap_outer_middleware(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "beauty_experts_bot/venv/lib/python3.11/site-packages/aiogram/dispatcher/middlewares/error.py", line 25, in __call__
    return await handler(event, data)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "beauty_experts_bot/venv/lib/python3.11/site-packages/aiogram/dispatcher/middlewares/user_context.py", line 27, in __call__
    return await handler(event, data)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "beauty_experts_bot/venv/lib/python3.11/site-packages/aiogram/fsm/middleware.py", line 39, in __call__
    return await handler(event, data)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "beauty_experts_bot/venv/lib/python3.11/site-packages/aiogram/dispatcher/event/telegram.py", line 120, in trigger
    return await wrapped_inner(event, kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "beauty_experts_bot/venv/lib/python3.11/site-packages/aiogram/dispatcher/event/handler.py", line 42, in call
    return await wrapped()
           ^^^^^^^^^^^^^^^
  File "beauty_experts_bot/venv/lib/python3.11/site-packages/aiogram/dispatcher/dispatcher.py", line 275, in _listen_update
    return await self.propagate_event(update_type=update_type, event=event, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "beauty_experts_bot/venv/lib/python3.11/site-packages/aiogram/dispatcher/router.py", line 116, in propagate_event
    return await observer.wrap_outer_middleware(_wrapped, event=event, data=kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "beauty_experts_bot/venv/lib/python3.11/site-packages/aiogram/dispatcher/router.py", line 111, in _wrapped
    return await self._propagate_event(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "beauty_experts_bot/venv/lib/python3.11/site-packages/aiogram/dispatcher/router.py", line 136, in _propagate_event
    response = await observer.trigger(event, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "beauty_experts_bot/venv/lib/python3.11/site-packages/aiogram/dispatcher/event/telegram.py", line 120, in trigger
    return await wrapped_inner(event, kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "beauty_experts_bot/venv/lib/python3.11/site-packages/aiogram/dispatcher/event/handler.py", line 42, in call
    return await wrapped()
           ^^^^^^^^^^^^^^^
  File "beauty_experts_bot/src/handlers/basic.py", line 15, in start
    await db.add_user(
  File "beauty_experts_bot/src/services/sql.py", line 26, in add_user
    async with self.db_pool.acquire() as connection:
  File "beauty_experts_bot/venv/lib64/python3.11/site-packages/asyncpg/pool.py", line 220, in release
    raise ex
  File "beauty_experts_bot/venv/lib64/python3.11/site-packages/asyncpg/pool.py", line 210, in release
    await self._con.reset(timeout=budget)
  File "beauty_experts_bot/venv/lib64/python3.11/site-packages/asyncpg/connection.py", line 1366, in reset
    await self.execute(reset_query, timeout=timeout)
  File "beauty_experts_bot/venv/lib64/python3.11/site-packages/asyncpg/connection.py", line 317, in execute
    return await self._protocol.query(query, timeout)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "asyncpg/protocol/protocol.pyx", line 323, in query
  File "asyncpg/protocol/protocol.pyx", line 707, in asyncpg.protocol.protocol.BaseProtocol._check_state
asyncpg.exceptions._base.InterfaceError: cannot perform operation: another operation is in progress

Мой запрос выглядит так:
async def add_user(self, user_id: int, username: str, name: str) -> None:
        try:
            async with self.db_pool.acquire() as connection:
                await connection.execute("""INSERT INTO user (id, username, name) VALUES (?, ?, ?)""",
                                         [user_id, username, name])
        except UniqueViolationError:
            pass

Вызов этого запроса в боте:
db = DataBase()

async def start(message: Message) -> None:
    await db.add_user(
        user_id=message.from_user.id,
        username=message.from_user.username,
        name=message.from_user.full_name
    )

Я подозреваю что ошибка в неправильной работе с асинхронностью но не могу понять в чем, также прилагаю код запуска бота:
from aiogram import Bot, Dispatcher
import asyncio
from aiogram.enums.parse_mode import ParseMode

from config import Config
from handlers import basic, specialist, admin
from utils.commands import set_commands


async def start():
    bot = Bot(token=Config.TOKEN, parse_mode=ParseMode.HTML)
    dp = Dispatcher(bot=bot)

    # REGISTER HANDLERS
    basic.register_handlers(dp=dp)
    specialist.register_handlers(dp=dp)
    admin.register_handlers(dp=dp)

    await set_commands(bot=bot)

    try:
        await dp.start_polling(bot)
    finally:
        await bot.send_message(chat_id=Config.ADMIN_ID, text="<b>BOT STOPPED</b>")
        await bot.session.close()

if __name__ == "__main__":
    asyncio.run(start())
  • Вопрос задан
  • 898 просмотров
Решения вопроса 1
@Maxwell012 Автор вопроса
Решил проблему что начал вызывать create_pool не с __init__ что содержиться в Database, а непосредственно с первоначальной функции async def start в которой запускается сам бот. Причина ошибки в том что асинхронные петли конфликтовали между собой
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

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