On Nov 27, 2013, at 12:48 PM, Amir Elaguizy <[email protected]> wrote:

> If I have a model like:
> 
> class Test(Base):
>     value = sqlalchemy.Column(db.String)
> 
> and I have a function like:
> 
> def on_value_change(model, oldValue):
>     # Do stuff
> 
> 
> I'd like on_value_change called *after* Test.value has been changed

yeah there’s been a bit of discussion about that but it isn’t present in a 
simple way.   attribute mechanics already take up a lot of overhead and add 
lots of complexity so adding an “after” event isn’t something I’m in a hurry to 
do.

In the rare occasions that I need this, sometimes what I will do is, just set 
the value within the before event, then work with it - I haven’t done this much 
so YMMV:

@event.listens_for(A.data, "set")
def set(target, value, oldvalue, initiator):
    target.__dict__['data'] = value
    work_with(target)
    return value

the reason __dict__ is used is otherwise you trigger an endless loop with the 
event.     The reason doing things in this way is dangerous (and why it’s extra 
hard to make this work) is that if you pass around “target” to other parts of 
your app, which are themselves doing things with attributes, now you have a 
nesting pattern going on that can easily enter more endless recursion types of 
issues.  

usually what I’ll do is just stick to simple things and use a descriptor like a 
synonym or a hybrid to set the value, which does what it needs after the set 
event. that’s pretty much the normal Python way of doing this sort of thing in 
any case.    Attribute events are in particular tailored towards validating / 
processing the immediate value given, not so much calling out into the bigger 
ecosystem of the application, as it is already occurring within a critical part 
of the attribute mechanics.


Attachment: signature.asc
Description: Message signed with OpenPGP using GPGMail

Reply via email to