I have a case where I 'm using threadlocal scoped_sessions and I'm storing
a file during a transaction. I want to delete the file if the transaction
rolls back for any reason. To handle this I use the event system,
something like so:
def write_data(file_path, data):
with open(file_path, "w") as fp:
fp.write(data)
#set up a rollback handler...
def delete_file(session, previous_transaction):
os.remove(file_path) # <--- BREAKPOINT HERE
ormSess = globalenv.LocalThreadData.OrmSess
sa.event.listen(orm_session, "after_soft_rollback",
delete_file, once=True)
What I'm currently finding is that the delete_file handler is firing off
long after the session it was hooked to is gone. I'm definitely calling
.remove() on the scoped_session.
When I put a breakpoint inside the handler, you can see that there are two
entirely different sessions.
The rollback is being called (code not shown) on an object at
0x7f18f8154910:
>>> orm_session.rollback
<bound method scoped_session.do of <sqlalchemy.orm.scoping.scoped_session
object at *0x7f18f8154910*>>
This fires off the handler for dead-and-gone (or so I thought) session.
Down the stack and inside the handler you can see that the session passed
in does not match:
>>> session # the listener arg
<sqlalchemy.orm.session.Session object at *0x5462b90*>
Again, these are within the same call stack.
Why would the handler on an old session be getting called? Am I
misunderstanding something here? Is there a proper way to get rid of all
event handlers on a session? I know that listeners can be removed
individually, but I thought scoped_session.remove() would make this
unnecessary.
Thanks,
Russ
--
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 [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.