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.
signature.asc
Description: Message signed with OpenPGP using GPGMail
