Thank you, i got it working now. For future reference: Before creating a sa class with something like:
type(typename, (Base,), classdict) I first create the classdict in which I define columns, __tablename__, etc, and validators (relationships I add later). The validators i create(using a subclass of dict as classdict in the type() call, and typedef being an object holding the definition to be used to create a sa class/table) with: def createValidator(self, typedef): # get names of attributes to be validated: names = [attr.name for attr in typedef.attributes \ if attr.validates()] #create validator method from validating method in the attr #definition in typedef: def validator(obj, name, value): return typedef[name].validate(value) #turn into sa "@validate" descriptor (i don't get the #mechanics completely, but still): validates(*names)(validator) #add to classdict self['validator'] = validator Hope this helps someone, open to questions ... Cheers, Lars On Apr 15, 7:20 pm, Michael Bayer <mike...@zzzcomputing.com> wrote: > If you can't establish the event at class declaration time, then the > @event.listens_for/event.listen() paradigm > (seehttp://docs.sqlalchemy.org/en/latest/core/event.htmlfor background) can > be applied to the class-bound attribute (which here is "Positive.value") at > any time. "Positive.value" is an attribute generated by the mapping which is > a result of using the declarative base. > > On Apr 15, 2012, at 1:10 PM, lars van gemerden wrote: > > > > > > > > > OK, this helps, so how do i do this if i do not know the name of the > > attribute to be checked in advance(the "value" in > > @validates("value") )? > > > On Apr 15, 6:52 pm, Michael Bayer <mike...@zzzcomputing.com> wrote: > >> using type() is equivalent to using a class declaration. The end result > >> is the same, as are the mechanics of what goes on both from a Python as > >> well as a SQLAlchemy perspective. So this works: > > >> Positive = type("Positive", (Base,), dict(__tablename__ = > >> "positives", value = Column(Integer))) > > >> @event.listens_for(Positive.value, "set") > >> def checkvalue(target, value, oldvalue, initiator) > >> assert value > 0 > > >> and also, since type() is equivalent to a class declaration, you can still > >> use @validates, if you pass the function into the class dictionary, so > >> that it is part of the class before declarative sends it off to mapper(): > > >> @validates("value") > >> def checkvalue(self, name, value): > >> assert value > 0 > >> return value > > >> Positive = type("Positive", (Base,), dict(__tablename__ = > >> "positives", value = Column(Integer), checkvalue=checkvalue)) > > >> On Apr 15, 2012, at 12:37 PM, lars van gemerden wrote: > > >>> I don't know what "@validates hangs a marker of the method that > >>> mapper() uses when it instruments the class" means. I guess my > >>> question now becomes: How do I add the event.listens_for descriptor to > >>> the class, since i do not have a class declaration in the traditional > >>> sense? > > >>> On Apr 15, 4:29 pm, Michael Bayer <mike...@zzzcomputing.com> wrote: > >>>> @validates hangs a marker of the method that mapper() uses when it > >>>> instruments the class, so if the class is already mapped then that train > >>>> has left the station. Taking a cab instead, you can just add the > >>>> attribute event directly: > > >>>> @event.listens_for(Positive.value, "set") > >>>> def checkvalue(target, value, oldvalue, initiator) > >>>> assert value > 0 > > >>>> if you want to return a new, mutated value then add retval=True to > >>>> listens_for(). > > >>>> On Apr 15, 2012, at 8:22 AM, lars van gemerden wrote: > > >>>>> Hi, > > >>>>> I need a way to dynamically add a validates method to a already > >>>>> created sqla class. > > >>>>> In a normal class declaration you can add a validator by: > > >>>>> class Positive(Base): > >>>>> __tablename__ = "positives" > >>>>> value = Column(Integer) > > >>>>> def checkvalue(self, name, value): > >>>>> assert value > 0 > >>>>> return value > >>>>> validates("value")(checkvalue) > > >>>>> However if you get the class dynamically: > > >>>>> Positive = type("Positive", (Base,), dict(__tablename__ = > >>>>> "positives", value = Column(Integer))) > > >>>>> I can't figure out how to add the validator, either in the type() call > >>>>> or afterwards. > > >>>>> Cheers, Lars > > >>>>> -- > >>>>> 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 > >>>>> athttp://groups.google.com/group/sqlalchemy?hl=en. > > >>> -- > >>> 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 > >>> athttp://groups.google.com/group/sqlalchemy?hl=en. > > > -- > > 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 > > athttp://groups.google.com/group/sqlalchemy?hl=en. -- 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.