PS: the validate(value) method in typedef[name] is a normal method, throwing exception on errors and returning the value when OK.
On Apr 16, 2:01 pm, lars van gemerden <[email protected]> wrote: > 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 <[email protected]> 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.htmlforbackground) 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 <[email protected]> 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 <[email protected]> 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 [email protected]. > > >>>>> To unsubscribe from this group, send email to > > >>>>> [email protected]. > > >>>>> 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 [email protected]. > > >>> To unsubscribe from this group, send email to > > >>> [email protected]. > > >>> 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 [email protected]. > > > To unsubscribe from this group, send email to > > > [email protected]. > > > 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 [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
