On Aug 28, 2008, at 8:11 AM, Cecil Westerhof wrote:

>
> I was just wondering if the folowing possible.
>
> A record has severall groups connected through a N:M relation.
> But it also has a parent. What I would like is that all the groups
> from the parent (and its parent, etc.) also are seen as group for the
> record.
> When the parent has a group added or removed that should then be
> 'visible' at the child.
> Not a very good description I am afraid, so I'll try to give an  
> example.
>
> Say I have the groups G1, G2, G3, G4 and G5.
> I have the records R1 and R2. R1 is the parent of R2 and does not have
> a parent itself.
>
> If R1 has the groups G1 and G2 and R2 has the groups G2, G4 and G5,
> then when asking the list of groups of R2 should give, G1, G2, G4 and
> G5.
> When quering for records that have group G1, both R1 and R2 should  
> be returned.
>
> When adding G3 to R1 the list for R2 should be: G1, G2, G3, G4 and G5.
> When removing G1 from R1 the list for R2 should be: G2, G3, G4 and G5.
> When removing G2 from R1 the list for R2 should be: G2, G3, G4 and G5.
> (R2 has itself also group G2.)
>
> Is this possible with sqlalchemy or has this to be done by hand?

I wouldn't say "by hand".   An element's groups are basically its own  
groups unioned with the groups of its parent.    So a simple recursion  
is the simplest way to form this group, but this only handles the  
"object graph" side of the equation, not the "Query" side.

Suppose a mapping like:

mapper(MyObject, mytable, properties={
        'groups':relation(Group, collection_class=set),
        'parent':relation(MyObject, remote_side=mytable.c.id)
})

MyObject could return the "full groups" using:

class MyObject(object):
        @property
        def full_groups(self):
                if self.parent:
                        return self.groups.union(self.parent.full_groups)       
                else:
                        return self.groups

On the Query side, the basic job is to formulate joins to the parent,  
which has the inherent issue that each level of depth corresponds to  
another join.  For the R1/R2 example it looks like:

parent_alias = aliased(MyObject)
sess 
.query 
(MyObject 
).outerjoin 
(parent_alias.parent).filter(or_(MyObject.groups.contains(somegroup),  
parent_alias.groups.contains(somegroup))

You can attempt to create a generalized function for the query above  
which is given N, number of levels to be queried, and then creates the  
joins N times as needed.  An example of this technique is in examples/ 
elementtree/adjacency_list.py .




--~--~---------~--~----~------------~-------~--~----~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to