Search code examples
python-3.xpython-asyncioasyncpgaiogram

asyncpg + aiogram. cannot perform operation: another operation is in progress


How I can fix it? I played with it a lot and for a long time, but nothing came of it.

sql_db.py:

import asyncio

import asyncpg


LOG_PG = {"database": 'test_bot',
          "user": 'misha',
          "password": '1234',
          "host": 'localhost'}


class Database:

    SELECT_USER_LANG = "SELECT lang FROM lang_set WHERE user_id = $1 AND bot_token = $2"

    def __init__(self, loop: asyncio.AbstractEventLoop):
        self.pool = loop.run_until_complete(
            asyncpg.create_pool(**LOG_PG)
        )

    async def get_lang(self, user_id, token):
        search_d = [user_id, token]

        res = await self.pool.fetchval(self.SELECT_USER_LANG, *search_d)

        if res is None:
            return "ru"
        return res

I tried to insert this loop everywhere, run without it, multiple combinations in the code itself. But nothing changed. I do not know how to describe the problem in more detail

main.py:

from aiogram import Bot, Dispatcher
from aiogram.types import Message

import asyncio
from sql_db import Database

loop = asyncio.get_event_loop()

token = "TOKEN"
dp = Dispatcher()
bot = Bot(token=token, parse_mode="HTML")

db = Database(loop)


async def echo_msg(message: Message):
    user_id = message.from_user.id

    await message.send_copy(user_id)
    await db.get_lang(user_id, token)


dp.message.register(callback=echo_msg)

if __name__ == '__main__':
    dp.run_polling(bot, skip_updates=True)

error:

...
  File "/home/mickey/Desktop/chat_admin/venv/lib/python3.8/site-packages/asyncpg/pool.py", line 867, in release
    return await asyncio.shield(ch.release(timeout))
  File "/home/mickey/Desktop/chat_admin/venv/lib/python3.8/site-packages/asyncpg/pool.py", line 224, in release
    raise ex
  File "/home/mickey/Desktop/chat_admin/venv/lib/python3.8/site-packages/asyncpg/pool.py", line 214, in release
    await self._con.reset(timeout=budget)
  File "/home/mickey/Desktop/chat_admin/venv/lib/python3.8/site-packages/asyncpg/connection.py", line 1367, in reset
    await self.execute(reset_query, timeout=timeout)
  File "/home/mickey/Desktop/chat_admin/venv/lib/python3.8/site-packages/asyncpg/connection.py", line 318, 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


Solution

  • Works through such a launch. It must be turned on through the aiogram. I do not know how to formulate, but I was lucky to understand the problem

    ...
    data_ = {}
    
    
    class Database:
    
        def __init__(self, pool: asyncpg.create_pool):
            self.pool = pool
    
        async def get_lang(self, user_id, token):
            search_d = [user_id, token]
    
            async with self.pool.acquire() as conn:
                res = await conn.fetchval(SELECT_USER_LANG, *search_d)
    
            if res is None:
                return "ru"
            return res
    
    
    async def create_pool():
        pool = await asyncpg.create_pool(**LOG_PG)
        data_["db"] = Database(pool)
    
    
    async def echo_msg(message: Message):
        user_id = message.from_user.id
    
        await message.send_copy(user_id)
        await data_["db"].get_lang(user_id, token)
    
    dp.message.register(callback=echo_msg)
    
    if __name__ == '__main__':
        dp.startup.register(create_pool) # ANSWER
        dp.run_polling(bot, skip_updates=True)