I've done some more playing here and I think I can see why the
multiple contains_eager options dont work on a self-referential
mapping.

Here's my example again:

ali = trees.alias()
ali2 = trees.alias()
statement = trees.outerjoin(ali,
and_(trees.c.node_id==ali.c.parent_node_id,
ali.c.node_name.in_('node2')))
statement = statement.outerjoin(ali2,
and_(ali.c.node_id==ali2.c.parent_node_id,
ali2.c.node_name.in_('subnode2')))
statement = statement.select().where(trees.c.parent_node_id==None)
query = create_session().query(TreeNode)\
                                        .from_statement(statement)\

.options(contains_eager('children', alias=ali),

contains_eager('children.children', alias=ali2))
test = query.one()

The first contains_eager goes off without a hitch. However the second
one hits a problem in PropertyOption._get_properties when it tries to
use the mapper belonging to the first 'children' property as the basis
for the next 'children' property. If these were different mappers then
there wouldn't be a problem, but as this is a self-referential mapper
we end up getting the same mapper back and overwriting the first
'children' property with the second one.

The result is that we always get the last alias in the chain with test.children.

It looks to me like self-referential joins created by the orm must
handle this by creating secondary mappers. I'm a bit off the beaten
track here and making it from a sql statement so those mappers never
get created.

At a glance it looks like _get_properties could create a secondary
mapper for a property if the next mapper in line was the same as the
current one (mapper == prop.mapper) and I'll give that a shot, but
then I'm not looking at the bigger picture of how PropertyOption is
used.

That was a bit of a mouthful, so if it doesn't make any sense then
please ask me to clarify and I'll do my best.

As an aside, I've worked around this issue a bit using add_entity and
I'm seeing a big performance improvement. Using contains_eager would
allow me to cut down significantly on the number of requests I'm
performing.

Thanks for the help!
Stephen Emslie

On 9/4/07, stephen emslie <[EMAIL PROTECTED]> wrote:
> > im going to play with this a little bit, but my first instinct is
> > that you might want to use contains_eager('children.children', ...)
> > for your deeper aliases.  but im not sure if something might prevent
> > that from working since i havent tested contains_eager in self-
> > referential scenarios as of yet.
>
> Thanks for taking a look. I did give
> contains_eager('children.children') a try as it seemed the most likely
> thing to work. Unfortunately it seemed to override the previous
> contains_eager relation, so I ended up with the root's 'children'
> relation coming up with subnode2 rather than node2 (i.e. skipping the
> first relation), but its nice to know I wasn't completely off that
> mark :)
>
> Stephen Emslie
>

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