MagicStack / MagicStack/asyncpg

asyncpg + aiogram is not working

Abierto
#927 1 comentario 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Lenguaje dominante
Python
Estrellas
8.1k
Forks
468
Métricas de merge de PR
Sin PR fusionados en 30 d

Descripción

  • asyncpg version: 0.25.0
  • PostgreSQL version: latest
  • Do you use a PostgreSQL SaaS? No
    the issue with a local PostgreSQL install?
    : No
  • Python version: 3.8
  • Platform: MacOS
  • Do you use pgbouncer?: No
  • Did you install asyncpg with pip?: Yes
  • If you built asyncpg locally, which version of Cython did you use?: -
  • Can the issue be reproduced under both asyncio and
    uvloop?
    : I dont know

There is some code abstraction coded with aiogram:

async def check_rights(message: types.Message):
			return await bot['db_pool'].fetch_query('SELECT is_admin FROM users WHERE id = $1::varchar(30) and username = $2::varchar(30)', 
			str(message.chat.id), message.from_user.username)


@bot_dispatcher.message_handler(check_rights, commands=['add_admin'])
async def add_admin(message: types.Message):
	print('is_admin!')

That's how bot['db_pool'] is created:

async def on_startup():
	db = Database()
	bot = Bot(token=token)
	bot_dispatcher = Dispatcher(bot)

	try:
		await db.setup_pool()
	except asyncpg.exception.InvalidPasswordError:
		logging.ERROR("Username or password if incorrect")
		exit(-1)
	else:
		bot['db_pool'] = db
		bot['getMeInfo'] = await bot.get_me()
		print(await bot['db_pool'].test())
		return bot, bot_dispatcher

And database object as well:

class Database(object):
	def __init__(self):
		if environ.get('DEBUG'):
			self.host, self.port, self.database = '127.0.0.1', 5432, 'test'
		else:
			self.host, self.port, self.database = environ.get('PG_HOST', 'postgres'), environ.get('PG_PORT', 5432), environ.get("PG_DATABASE")

	@property
	def get_pool(self):
		return self.pool

	async def setup_pool(self):
			self.pool = await create_pool(
				user = environ.get('PG_USERNAME'),
				password = environ.get('PG_PASSWORD'),
				host = self.host, port = self.port,
				database = self.database
			)

	async def fetch_query(self, query: str, *args):
		async with self.pool.acquire() as connection:
			async with connection.transaction():
				return await connection.fetchval(query, *args)

	async def test(self):
		return await self.fetch_query("select 2 ^ $1", 1)

Well if I am creating event loop like this:

loop = new_event_loop()
bot, bot_dispatcher = loop.run_until_complete(on_startup())

And starting bot like this:

if __name__ == "__main__":
	print(f"[+] Bot started with username: {bot['getMeInfo'].username}")
	executor.start_polling(bot_dispatcher, skip_updates=True)

I can't execute POOL methods, for example:

async def check_rights(message: types.Message):
			return await bot['db_pool'].fetch_query('SELECT is_admin FROM users WHERE id = $1::varchar(30) and username = $2::varchar(30)', 
			str(message.chat.id), message.from_user.username)

Error trace:

Task exception was never retrieved
future: <Task finished name='Task-32' coro=<Dispatcher._process_polling_updates() done, defined at /Users/riven/Desktop/Projects/botname/src/venv/lib/python3.8/site-packages/aiogram/dispatcher/dispatcher.py:407> exception=InterfaceError('cannot perform operation: another operation is in progress')>
Traceback (most recent call last):
  File "/Users/riven/Desktop/Projects/botname/src/venv/lib/python3.8/site-packages/aiogram/dispatcher/dispatcher.py", line 415, in _process_polling_updates
    for responses in itertools.chain.from_iterable(await self.process_updates(updates, fast)):
  File "/Users/riven/Desktop/Projects/botname/src/venv/lib/python3.8/site-packages/aiogram/dispatcher/dispatcher.py", line 235, in process_updates
    return await asyncio.gather(*tasks)
  File "/Users/riven/Desktop/Projects/botname/src/venv/lib/python3.8/site-packages/aiogram/dispatcher/handler.py", line 116, in notify
    response = await handler_obj.handler(*args, **partial_data)
  File "/Users/riven/Desktop/Projects/botname/src/venv/lib/python3.8/site-packages/aiogram/dispatcher/dispatcher.py", line 256, in process_update
    return await self.message_handlers.notify(update.message)
  File "/Users/riven/Desktop/Projects/botname/src/venv/lib/python3.8/site-packages/aiogram/dispatcher/handler.py", line 107, in notify
    data.update(await check_filters(handler_obj.filters, args))
  File "/Users/riven/Desktop/Projects/botname/src/venv/lib/python3.8/site-packages/aiogram/dispatcher/filters/filters.py", line 72, in check_filters
    f = await execute_filter(filter_, args)
  File "/Users/riven/Desktop/Projects/botname/src/venv/lib/python3.8/site-packages/aiogram/dispatcher/filters/filters.py", line 56, in execute_filter
    return await filter_.filter(*args, **filter_.kwargs)
  File "__main__.py", line 65, in check_rights
    return await bot['db_pool'].fetch_query('SELECT is_admin FROM users WHERE id = $1::varchar(30) and username = $2::varchar(30)',
  File "/Users/riven/Desktop/Projects/botname/src/database.py", line 33, in fetch_query
    return await connection.fetchval(query, *args)
  File "/Users/riven/Desktop/Projects/botname/src/venv/lib/python3.8/site-packages/asyncpg/pool.py", line 993, in __aexit__
    await self.pool.release(con)
  File "/Users/riven/Desktop/Projects/botname/src/venv/lib/python3.8/site-packages/asyncpg/pool.py", line 867, in release
    return await asyncio.shield(ch.release(timeout))
  File "/Users/riven/Desktop/Projects/botname/src/venv/lib/python3.8/site-packages/asyncpg/pool.py", line 224, in release
    raise ex
  File "/Users/riven/Desktop/Projects/botname/src/venv/lib/python3.8/site-packages/asyncpg/pool.py", line 214, in release
    await self._con.reset(timeout=budget)
  File "/Users/riven/Desktop/Projects/botname/src/venv/lib/python3.8/site-packages/asyncpg/connection.py", line 1367, in reset
    await self.execute(reset_query, timeout=timeout)
  File "/Users/riven/Desktop/Projects/botname/src/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

cannot perform operation: another operation is in progress - Which one? I am doing only 1 request to database 0-o

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza con database.py, especialmente con setup_pool y fetch_query, y luego sigue los puntos de entrada on_startup y check_rights que se muestran en el informe. Reproduce el caso de polling e inspecciona la ruta de adquisición y liberación del pool de asyncpg; se considera terminado cuando se explique qué operación superpuesta causa el InterfaceError y se documente una resolución verificada o una reproducción mínima.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
postgresql, python
Área
backend, database
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Estancado
Claridad
Necesita aclaración
Aptitud para principiantes
30/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.