flask-sqlalchemy: Listening for 'before_flush' throws sqlalchemy.exc.ArgumentError
Registering a listener for ‘before_commit’ (and ‘before_flush’) like so, where:
db = SQLAlchemy(app)
...
event.listen(db.session, 'before_commit', before_commit)
Throws the following exception:
@event.listens_for(db.session, "before_flush")
File "/home/environments/python3/lib/python3.3/site-packages/sqlalchemy/event/api.py", line 68, in decorate
listen(target, identifier, fn, *args, **kw)
File "/home/environments/python3/lib/python3.3/site-packages/sqlalchemy/event/api.py", line 49, in listen
_event_key(target, identifier, fn).listen(*args, **kw)
File "/home/environments/python3/lib/python3.3/site-packages/sqlalchemy/event/api.py", line 22, in _event_key
tgt = evt_cls._accept_with(target)
File "/home/environments/python3/lib/python3.3/site-packages/sqlalchemy/orm/events.py", line 1142, in _accept_with
"Session event listen on a scoped_session "
sqlalchemy.exc.ArgumentError: Session event listen on a scoped_session requires that its creation callable is associated with the Session class.
Per the comment in this thread from Mike Bayer, it seems the issue is with the factory being passed to scoped_session not being a sessionmaker(): http://stackoverflow.com/questions/21322158/event-listener-on-scoped-session
Stepping through the code, it barfs in this method in line 1132 of sqlalchemy/orm/events.py:
@classmethod
def _accept_with(cls, target):
if isinstance(target, scoped_session):
target = target.session_factory
if not isinstance(target, sessionmaker) and \
(
not isinstance(target, type) or
not issubclass(target, Session)
):
raise exc.ArgumentError(
"Session event listen on a scoped_session "
"requires that its creation callable "
"is associated with the Session class.")
db.session.session_factory is of type functools.partial, which angers SQLAlchemy.
About this issue
- Original URL
- State: closed
- Created 10 years ago
- Comments: 15 (5 by maintainers)
You can work around this by registering the event handler on the underlying session class instead of on the created session object: