On Aug 30, 2012, at 10:32 AM, Tony Moutaux wrote: > Hi there ! > > I'm going mad looking for a solution for what seems a simple problem. > > When object A is updated, I also want object B to be updated, using some > computation based on A new values. > From now, I can detect when A is modified using after_update. > > What I try is to look at event Session.after_flush, if in Session.dirty there > is an instance of A, I call the update of B. Within after_flush I can see > Session.dirty with the modified B. But no SQL UPDATE is issued at all. > > Any tip for me ?
You do this kind of thing most simply within the objects themselves, not as much in Session events, depending on how things are organized. Such as in the __init__() method of A, or by using an event listener on an attribute of A. Only if "some computation based on A new values" means that there are SQL-level functions which you need to get at, does the rationale for "after_update"/"after_flush" events to come up. Unfortunately you can't emit a flush() within any of these events, as they are already local to the flush() call itself. Nor can you change the state of the Session within any of the "after_" events, as the Session is already doing its work. You can add new state to the Session within the "after_flush_postexec()" method, however you'd need to call flush() again for those changes to be flushed. So the options: 1. if "some computation" is only "in-Python" computation, and *not* SQL functions, then set the state of B within object-level events, such as the __init__() of A, a @property on A, @validates events on A, or attribute events on A. 2.if "some computation" involves SQL functions: a. emit your modifications to B using only SQL statements and Session.execute(), not by adding any new state to the Session or re-flushing. b. pre-execute your SQL functions for A *outside* of the flush, then apply values to B as needed. c. use a second Session inside the event: def after_flush(session, flush_context): my_bs = figure_out_bs(session) new_session = Session(bind=session.connection()) new_session.add_all(my_bs) # this won't actually COMMIT the transaction as we are # already inside one new_session.commit() -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.