I got it working. The second example was really helpful. Thanks, Mike! Best regards, Bruno
On Wed, May 13, 2015 at 3:15 PM, Mike Bayer <mike...@zzzcomputing.com> wrote: > > > On 5/13/15 5:33 PM, Bruno Grande wrote: > > I was looking for a way of typecasting attributes that are mapped to > Integer columns as Python integers without having to commit to the database > first. On the IRC channel, I was pointed towards simple validators and > the @validates decorator. While this works, implementing validation using > this approach for all integer attributes across all classes seems > inefficient. > > I then looked into AttributeEvents with the idea of adding a listener to > the base class, but I can't seem to figure out a way for have the listener > listen to all attribute changes. The documentation > <http://docs.sqlalchemy.org/en/latest/orm/events.html#sqlalchemy.orm.events.AttributeEvents.set> > only gives examples for listening to specific attributes (see example code > below pulled from documentation). > > from sqlalchemy import event > > @event.listens_for(SomeClass.some_attribute, 'set') > def receive_set(target, value, oldvalue, initiator): > # ... (event handling logic) ... > > Hence, I was wondering if any of you would have a clever and > straightforward way of achieving type validation on all classes (at least > for integers for now). Thanks! > > *Extra Information* > Python 2.7.8 > SQLAlchemy 0.9.8 > > > So first off, in Python we do have the option of overriding a builtin > method called __setattr__(), which if you really wanted to intercept most > attribute set events, you could just do that. This is heavy-handed though > because it is called for all attribute sets everywhere and it would spend a > lot of time filtering out attributes it doesn't care about. > > Secondly, @validates and AttributeEvents are two versions of the same > thing - @validates is a shortcut for AttributeEvents, and the > AttributeEvents listener is set up on a per-attribute basis. So there's > not too much difference except how these are configured, and using the > AttributeEvents is better for programmatic attachment. You can also set > up such a listener for all mapped attributes everywhere, but again this is > too broad and such a listener again wastes lots of time filtering on which > events it cares about. > > With that information out of the way, the general strategy to listen to > events on things that are mapped such that the things which we're listening > to is also dynamic / programmatic is to apply event listeners to the > attributes we care about. There's more events that we make use of in order > to set up event listeners at the moment that these various attributes and > other things are mapped. There are a lot of ways to catch such events, but > the most easy one that was added mostly for this purpose is known as the > "attribute_instrument" event, which is called whenever a new class > attribute becomes part of a SQLAlchemy mapping. This is a good place where > you can check how this attribute is mapped and make decisions about what > kind of validation it should have. Two examples are provided, one which > illustrates how to apply a listener to all the events associated with a > base class, that is at > http://docs.sqlalchemy.org/en/rel_1_0/_modules/examples/custom_attributes/listen_for_events.html, > and there's also a recipe which I think is nicer that sets up validators > based on the column types, such as your Integer here, that is at > https://bitbucket.org/zzzeek/sqlalchemy/wiki/UsageRecipes/ValidateOnType. > > > > > Best regards, > Bruno > -- > 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 sqlalchemy+unsubscr...@googlegroups.com. > To post to this group, send email to sqlalchemy@googlegroups.com. > Visit this group at http://groups.google.com/group/sqlalchemy. > For more options, visit https://groups.google.com/d/optout. > > > -- > You received this message because you are subscribed to a topic in the > Google Groups "sqlalchemy" group. > To unsubscribe from this topic, visit > https://groups.google.com/d/topic/sqlalchemy/oadk2Qqfpmk/unsubscribe. > To unsubscribe from this group and all its topics, send an email to > sqlalchemy+unsubscr...@googlegroups.com. > To post to this group, send email to sqlalchemy@googlegroups.com. > Visit this group at http://groups.google.com/group/sqlalchemy. > For more options, visit https://groups.google.com/d/optout. > -- 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 sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at http://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.