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.

Reply via email to