[Sqlalchemy-tickets] Issue #2978: .listen() on Engine-level events fired from Connection does not w
Brought to you by:
zzzeek
|
From: Alan S. <iss...@bi...> - 2014-03-02 01:49:27
|
New issue 2978: .listen() on Engine-level events fired from Connection does not work for in-progress Sessions if it's the first listener https://bitbucket.org/zzzeek/sqlalchemy/issue/2978/listen-on-engine-level-events-fired-from Alan Shreve: Here's the succinct code explanation: sess = Session() sess.query(A).all() sqlalchemy.event.listen(engine, "before_execute", before_execute_cb) sess.query(A).all() # <--- USE THE SAME SESSION AS BEFORE That second query *does not* trigger before_execute_cb. I expect it to trigger that. However, if you do this: # Register dummy listener to force Connection's dispatch descriptor to join with Engine's sqlalchemy.event.listen(engine, "before_execute", noop_fn) sess = Session() sess.query(A).all() sqlalchemy.event.listen(engine, "before_execute", before_execute_cb) sess.query(A).all() # <--- USE THE SAME SESSION AS BEFORE This time, the second query *does* trigger before_execute_cb. A full set of cases: https://gist.github.com/inconshreveable/9300571 This is a very subtle problem in the initialization of the dispatcher on Connection objects. The bug is here: https://bitbucket.org/zzzeek/sqlalchemy/src/fa23570a338b53c813b6342fba0cacd4f5e61384/lib/sqlalchemy/engine/base.py?at=master#cl-66 I'm not well-versed enough in SQLAlchemy design to decide how to solve this, but my suggestion is probably: Connection objects should *always* join with the Engine's dispatch object and when registering a new event listener on the Engine's dispatch object, it needs to iterate each open connection and set _has_events to True. |