[sqlalchemy] Re: How to get the instance back from a PropComparator?

2009-09-27 Thread Michael Bayer


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
-~--~~~~--~~--~--~---



[sqlalchemy] Re: How to get the instance back from a PropComparator?

2009-09-27 Thread Yuen Ho Wong

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
-~--~~~~--~~--~--~---