you can explicitly create these many-to-many join relations and eager  
load them.

users = session.query(User).options(eagerload(User.groups)).all()

if you want to query for relations with a filter, AFAIK you need to  
define them as a separate relation.

class User(...)
     groups = relation("Group", primaryjoin=("User.id ==  
GroupMember.user_id"), secondaryjoin=("GroupMember.group_id ==  
Group.id"), secondary="GroupMember")
     large_groups = relation("Group", primaryjoin=("User.id ==  
GroupMember.user_id"), secondaryjoin=("GroupMember.group_id ==  
Group.id & Group.size > 10"), secondary="GroupMember")

users = session.query(User).options(eagerload(User.large_groups)).all()
users[0].large_groups # ...

On Sep 3, 2009, at 1:24 PM, Damon wrote:

>
> Thank you very much for the explanation. It is what I feared was the
> case.
>
> One of the great features we love about SA is the mappers, allowing us
> to define table relationships in such a way that we can decide what
> table(s) around which to "pivot", giving us different ways of
> returning data even when processed from the same query. It seemed to
> us that if the mappers are able to traverse all the joins necessary to
> render the mapped objects -- we greatly admire SA's ability to
> construct all the outer joins required to do this in one fell swoop --
> that it should also be possible to have SA follow similar logic to
> construct query objects as well -- in a completely analogous fasion --
> when supplied with filters.
>
> Alas that this is not the case. :(
>
> --Damon
>
> On Sep 3, 12:29 pm, "Michael Bayer" <mike...@zzzcomputing.com> wrote:
>> Damon wrote:
>>
>>>>> MUST we explicitly supply the join to such query objects? Or is  
>>>>> there
>>>>> some way that SA can figure out that tbl_people_documents is in
>>>>> between tbl_people and tbl_documents on its own? Perhaps there is
>>>>> something we can add to the tbl_people/tbl_documents object
>>>>> definitions that clues SA in?
>>
>>>> join on the relation.
>>
>>>> query(A).join(A.relation_to_b).filter(B.foo == 'bar')
>>
>>> The problem with that, from what we're trying to build, is that we
>>> have to explicitly know that relation object and supply it.
>>
>>> We want SA to *infer* the relationship between any two tables  
>>> based on
>>> the ORM relationships that we have already defined in our mapper
>>> objects.
>>
>> but you're asking for it to infer the join between *three* tables -  
>> i.e.
>> your association table.   The current SQLA functionality is that  
>> ORM-level
>> joins, that is joins which occur due to the presence of a  
>> relation(), must
>> be expressed explicitly in terms of the relation between the two  
>> entity
>> classes.     Right now only a SQL level join, that is joins which  
>> occur
>> due to the presence of a known foreign key between the two tables,  
>> is what
>> happens if you don't specify the relation() you'd like to join on.
>>
>> The proposed enhancement would require that we change the method  
>> used when
>> someone joins from A to B using query.join(), in that it would
>> specifically search for ORM-level relations, instead of relying upon
>> SQL-level joining which searches only for foreign keys between the  
>> two
>> tables.   It would also throw an error if there were any ambiguity
>> involved.   I'm not 100% sure but I think it's quite possible that  
>> we had
>> such a "assume the only relation() in use" feature a long time ago  
>> when
>> constructing joins, and it was removed in favor of explicitness,  
>> but I'd
>> have to dig through 0.3 functionality to see if that was the case.
>>
>> My initial take on this feature is -1 on this since I don't think  
>> being
>> explicit about an ORM relation is burdensome or a bad idea (plus we  
>> might
>> have already made this decision a long time ago).  We might just  
>> need some
>> better error messages when a join can't be found between "A" and  
>> "B" to
>> suggest that its only looking for immediate foreign keys in that  
>> case, not
>> ORM relations.
>>
>> Alternatively, SQL-expression level join() would "search" for any  
>> number
>> of paths from table A to table B between any other tables that may  
>> create
>> a path between them.  that would also find the association table  
>> between A
>> and B and create a longer series of joins without ORM  
>> involvement.   I'm
>> strongly -1 on such a feature as the expression language shouldn't be
>> tasked with performing expensive graph traversals just to formulate  
>> a SQL
>> query, and table.join()'s contract is that it produces a JOIN  
>> between only
>> two tables, not a string of joins.
> >


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