Async Event Listeners

372 views
Skip to first unread message

Brendan Blanchard

unread,
Feb 24, 2022, 2:56:52 PM2/24/22
to sqlalchemy
Hi all,

I've been having a lot of fun trying to optimize an async data retrieval system, but am in need of tracking when connections are checked in and out so I can debug overloading the connection pool. The documentation was of course helpful in the synchronous case for adding listeners on 'checkin' and 'checkout', but not so much for async.

I finally came across this SO post where the OP was getting a helpful error message stating that async listeners were not supported, and to use `{async_engine}.sync_engine` to register listeners to (which solves my problem, too), but wanted to check in about the error I'm getting instead. With SQLAlchemy 1.4.29 on Python 3.10 (with asyncpg),  the following produces a cryptic traceback rather than a pointed error message. Is this a consequence of partial support for async listeners at this time?

"""
async_engine = create_async_engine(...)
Session = sessionmaker(bind=async_engine, class_=AsyncSession)

@event.listens_for(async_engine, 'checkout')
def receive_checkout(dbapi_connection, connection_record, connection_proxy):
print(f'Session checked out at {datetime.now()}')
print(f'\t{dbapi_connection}')
print(f'\t{connection_record}')
print(f'\t{connection_proxy}')

async with Session() as session:
result = await session.execute(
text('SELECT version();')
)

print(result.scalar())
"""

"""
Error Traceback (most recent call last):
  File "/home/brendan/PycharmProjects/db_utils/venv/lib/python3.10/site-packages/sqlalchemy/event/base.py", line 104, in __getattr__
    ls = self._empty_listeners[name]
KeyError: 'checkout'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/brendan/PycharmProjects/db_utils/test/test_database.py", line 153, in test_listeners_on_async_engine
    asyncio.run(self.run_test_listeners_on_async_engine())
  File "/usr/lib/python3.10/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/usr/lib/python3.10/asyncio/base_events.py", line 641, in run_until_complete
    return future.result()
  File "/home/brendan/PycharmProjects/db_utils/test/test_database.py", line 139, in run_test_listeners_on_async_engine
    def recieve_checkout(dbapi_connection, connection_record, connection_proxy):
  File "/home/brendan/PycharmProjects/db_utils/venv/lib/python3.10/site-packages/sqlalchemy/event/api.py", line 160, in decorate
    listen(target, identifier, fn, *args, **kw)
  File "/home/brendan/PycharmProjects/db_utils/venv/lib/python3.10/site-packages/sqlalchemy/event/api.py", line 115, in listen
    _event_key(target, identifier, fn).listen(*args, **kw)
  File "/home/brendan/PycharmProjects/db_utils/venv/lib/python3.10/site-packages/sqlalchemy/event/registry.py", line 213, in listen
    dispatch_collection = getattr(target.dispatch, identifier)
  File "/home/brendan/PycharmProjects/db_utils/venv/lib/python3.10/site-packages/sqlalchemy/event/base.py", line 106, in __getattr__
    raise AttributeError(name)
AttributeError: checkout
"""

I'm happy to contribute to documentation if it'll be of any help.

Cheers,
Brendan

Mike Bayer

unread,
Feb 24, 2022, 3:30:40 PM2/24/22
to noreply-spamdigest via sqlalchemy
the error seems like what would happen right now, sure. 

we have a complete doc section now on setting up event handlers with async objects:

--
SQLAlchemy -
The Python SQL Toolkit and Object Relational Mapper
 
 
To post example code, please provide an MCVE: Minimal, Complete, and Verifiable Example. See http://stackoverflow.com/help/mcve for a full description.
---
You received this message because you are subscribed to the Google Groups "sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+...@googlegroups.com.

Reply all
Reply to author
Forward
0 new messages