[sqlalchemy] Re: dynamically adding a validates method

2012-04-16 Thread lars van gemerden
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  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  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  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  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 "sqla

[sqlalchemy] Re: dynamically adding a validates method

2012-04-16 Thread lars van gemerden
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  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  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  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 G

Re: [sqlalchemy] Re: dynamically adding a validates method

2012-04-15 Thread Michael Bayer
If you can't establish the event at class declaration time, then the 
@event.listens_for/event.listen() paradigm (see 
http://docs.sqlalchemy.org/en/latest/core/event.html for 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  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  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 at 
> http://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.



[sqlalchemy] Re: dynamically adding a validates method

2012-04-15 Thread lars van gemerden
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  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  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 at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] Re: dynamically adding a validates method

2012-04-15 Thread Michael Bayer
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  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 at 
> http://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.



[sqlalchemy] Re: dynamically adding a validates method

2012-04-15 Thread lars van gemerden
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  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 at 
http://groups.google.com/group/sqlalchemy?hl=en.