-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Dec 5, 2011, at 11:58 AM, Daniel Nouri wrote:

> Say I have a class that derives from a Node class that has a 'parent'
> relationship (using 'parent_id' and 'id' fields):
> 
>    from sqlalchemy.ext.hybrid import hybrid_property
> 
>    class MyClass(Node):
>        @hybrid_property
>        def grandparent(self):
>            return self.parent.parent
> 
>        @grandparent.expression
>        def grandparent(cls):
>            pass # hmm?
> 
> How would I go about the implementing the grandparent hybrid
> expression?  What I have is a boolean clause list with two comparisons
> of 'parent_id' and 'id' using aliases (not included in the example).
> I was hoping I could return that but it's not what it expects.
> 
> Thanks for your help.

yeah so this is where @hybrid can....not really do the whole thing.    
Basically when you use a hybrid on a relationship, the @expression version 
returns whatever it is that's most useful, given the context that you'd be 
using it within.  It of course cannot imply the automatic generation of join() 
or anything like that, which is a manual thing...unless you had @expression 
return a function that would process a given Query, which is pretty nasty and 
not really helpful.

So in this case, I'm not even sure @expression can return a concept that is 
meaningfully the "grandparent" - usually the best it can do is return 
"cls.parent", but in this case that directly contradicts that it's called 
"grandparent".  

that would look like:

q = session.query(MyClass).\
          join(parent_alias, MyClass.grandparent).\
          filter(parent_alias.grandparent == some_object)

which is nasty because .grandparent is the same as .parent, so don't do that.

 If it returned an aliased(cls).parent, then that alias object would need to be 
memoized so that you can refer to it multiple times in the query (which is 
possible).  That would make the usage something like:

parent _alias = aliased(MyClass)

q = session.query(MyClass).\
        join(parent_alias, MyClass.parent).\
        join(MyClass.grandparent, parent_alias.parent).\
        filter(MyClass.grandparent == some_node)

which also makes little sense, so....probably don't do that either :).

another awful thought I had, return a query option that runs it through 
join(..., aliased=True):

q = session.query(MyClass).\
         options(MyClass.grandparent).\
         filter_by(id=id_of_my_grandparent)

I'd need to enhance options() a bit, or provide some other method to Query like 
query.with_transformation(fn) that runs the query through a given callable.

the query above is completely opaque and pretty much can do just the one thing 
it's been set up to do, not very useful :)

or if one were to really go nuts with that approach and produce a comparator 
with an __eq__() method, maybe even:

session.query(MyClass).with_transformation(MyClass.grandparent==some_parent)

but I consider that to be kind of a novelty.   Or maybe not, 
with_transformation() might be a handy method to add in any case.

so yeah @expression.grandparent is not really very useful given the explicit 
nature of the Query object, unless you seek to build tricks that build up the 
Query behind the scenes.    





> --
> http://danielnouri.org
> 
> -- 
> 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.
> 

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (Darwin)
Comment: GPGTools - http://gpgtools.org

iQEcBAEBAgAGBQJO3QJ2AAoJEDMCOcHE2v7hTjUIAMxDwOtCrK2boRqX7qTGe3FY
RXxX32oF7TJhI5+OpBfruKSCM3B4Ts6FtRIEAdczsFOGTAviaSvIhChPmQEf8sr+
RVXtaerId4QlL5ME5AsXaeHlVgGRkULOFmwrHlmLk0BJqG6KFJTR8+n7BhWj5ZKk
muotloakfXkeNrlxdBiqIbPemHi8C2gH8Kkmpak/yJgNqv05dQj3rHhGZma3RpLQ
D2wKTkNe2zipcZkK1oEFWbRJzDfFhVZxCHS8Cvfc3c413nJdm3WCpjziKVDW5ws8
q+fNWAHhIzB7ttE6x51pqwOapvXgmo2UJqUjFXnjjyEY3TDQ9AtXTPwKhql0ToY=
=1MI+
-----END PGP SIGNATURE-----

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