Ah ha, so SQL expression operations are all translated directly to
their appropriate SQL clauses. This makes sense I guess. Too bad this
means I have to implement the same function twice, one in Python and
another in SQL. Would be nice if there was some magic to morph custom
properties to have some capabilities to operate on the Python side,
but I guess that would be much slower.

Right now I solved this problem with this new comparator:

    class AgeComparator(PropComparator):

        def __clause_element__(self):
            return (func.datediff(func.curdate(),
self.mapper.c.date_of_birth) / 365)

        def operate(self, op, *args, **kwargs):
            return op(self.__clause_element__(), *args, **kwargs)

Thanks a lot!


On Sep 27, 1:14 pm, Michael Bayer <mike...@zzzcomputing.com> wrote:
> On Sep 27, 2009, at 12:49 PM, Yuen Ho Wong wrote:
>
>
>
>
>
>
>
> > So I have this following code:
>
> > class User(Base):
> >     ....
>
> >     class AgeComparator(PropComparator):
>
> >     def __lt__(self, other):
> >         pass
>
> >     def __gt__(self, other):
> >         pass
>
> >     def __eq__(self, other):
> >         pass
>
> >     def __ne__(self, other):
> >         return not (self == other)
>
> >     def __le__(self, other):
> >         return self < other or self == other
>
> >     def __ge__(self, other):
> >         return self > other or self == other
>
> >     @comparable_using(AgeComparator)
> >     @property
> >     def age(self):
> >         today = date.today()
> >         age = today - (self.date_of_birth or (today + 1))
> >         return age.days / 365
>
> > All I want to do is this:
>
> > user = User(date_of_birth=date.today())
> > session.add(user)
> > new_borns = session.query(User).filter(User.age == 0).all()
>
> > The doc for comparable_property() suggests that this is possible, but
> > I'm lost finding my way to call the descriptor bound on this instance.
>
> The age(self): function is only called when you actually have an  
> instance, such as:
>
> user = sess.query(User).get(10)
> print "age is: " , user.age
>
> The point of @comparable_using associates the behavior of  
> AgeComparator to the "age" attribute on the User class, no instance:
>
> User.age == 0
>
> User.age == 0 is going to invoke the __eq__() method on the  
> AgeComparator you created.  There is no instance within the query()  
> call here.   __eq__() needs to return a clause expression of your  
> choosing, which must be expressed in terms of SQL functions, since  
> you're rendering a SQL statement.   That's a little tricky here since  
> there's a lot of date arithmetic there, but using hypothetical  
> functions it would look something like:
>
> def __eq__(self, other):
>     return func.count_days(func.date_diff(func.now() -  
> mapped_table.c.date_of_birth)) / 365
>
> The comparable_using example should probably include a short  
> PropComparator to give more context.  A sample comparator is at:
>
> http://www.sqlalchemy.org/docs/05/mappers.html#custom-comparators
>
>
>
>
>
> > The problem I have is that the ComparableProperty only gave itself and
> > the mapper to the comparator, but the user instance is nowhere to be
> > found inside either ComparableProperty, PropComparator or mapper. I'd
> > appreciate some help here if this is at all possible. The documents on
> > this is a little too sparse IMO.
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to