I noticed that the path_based_options branch has been merged, which
looks great as a way to eager-load deep relationships in queries built
with from statements (ie: query.from_statement). I noticed some
strange behavior and I want to check that I've got the right idea
before I open any tickets:

Both of them come from using contains_eager with a path. After setting
up a mapping similar to the AdjacencyTree example in trunk I'm joining
to the same table twice with aliases like this (This doesn't really
show why I'm doing this in the first place, but it should illustrate
the problem):

ali = trees.alias()
ali2 = trees.alias()
statement = trees.outerjoin(ali, trees.c.node_id==ali.c.parent_node_id)
statement = statement.outerjoin(ali2, ali.c.node_id==ali2.c.parent_node_id)
statement = 
statement.select(use_labels=True).where(trees.c.parent_node_id==None)
query = create_session().query(TreeNode).from_statement(statement)

So I have a query created from the statement, which should be the
table joined to itself twice. Now if I set two contains_eager options
using the new path behaviour:

root = query.options(contains_eager('children'),
contains_eager('children.children')).one()
(Pdb) root.children
{u'rootnode': rootnode (1,None, 139201708)
}
(Pdb) root.children['rootnode'].children
{u'rootnode': rootnode (1,None, 139201708)
}
(Pdb) root.children['rootnode'].children['rootnode'].children
{u'rootnode': rootnode (1,None, 139201708)
}

This looks like root thinks that it is it's own child. It might be
that I need to use an alias with the contains_eager option, but if I
do:

root = query.options(contains_eager('children', alias=ali),
contains_eager('children.children', alias=ali2)).one()

Traceback (most recent call last):
  File "basic_tree.py", line 88, in <module>
    root = query.options(contains_eager('children', alias=ali),
contains_eager('children.children', alias=ali2)).one()
  File "/home/stephen/src/sqlalchemy/lib/sqlalchemy/orm/query.py",
line 641, in one
    ret = list(self[0:2])
  File "/home/stephen/src/sqlalchemy/lib/sqlalchemy/orm/query.py",
line 655, in __iter__
    return self._execute_and_instances(context)
  File "/home/stephen/src/sqlalchemy/lib/sqlalchemy/orm/query.py",
line 660, in _execute_and_instances
    return iter(self.instances(result, querycontext=querycontext))
  File "/home/stephen/src/sqlalchemy/lib/sqlalchemy/orm/query.py",
line 721, in instances
    self.select_mapper._instance(context, row, result)
  File "/home/stephen/src/sqlalchemy/lib/sqlalchemy/orm/mapper.py",
line 1448, in _instance
    self.populate_instance(context, instance, row, **flags)
  File "/home/stephen/src/sqlalchemy/lib/sqlalchemy/orm/mapper.py",
line 1514, in populate_instance
    (newpop, existingpop, post_proc) =
selectcontext.exec_with_path(self, prop.key,
prop.create_row_processor, selectcontext, self, row)
  File "/home/stephen/src/sqlalchemy/lib/sqlalchemy/orm/query.py",
line 1223, in exec_with_path
    return func(*args, **kwargs)
  File "/home/stephen/src/sqlalchemy/lib/sqlalchemy/orm/interfaces.py",
line 487, in create_row_processor
    return 
self._get_context_strategy(selectcontext).create_row_processor(selectcontext,
mapper, row)
  File "/home/stephen/src/sqlalchemy/lib/sqlalchemy/orm/strategies.py",
line 593, in create_row_processor
    row_decorator = self._create_row_decorator(selectcontext, row,
selectcontext.path)
  File "/home/stephen/src/sqlalchemy/lib/sqlalchemy/orm/strategies.py",
line 580, in _create_row_decorator
    decorated_row = decorator(row)
  File "/home/stephen/src/sqlalchemy/lib/sqlalchemy/orm/strategies.py",
line 709, in decorate
    for c in prop.target.columns:
NameError: free variable 'prop' referenced before assignment in enclosing scope

So without aliases there is a cycle, but with aliases there's this
exception. Just for kicks I tried using the name of the alias instead
of the alias object:

root = query.options(contains_eager('children', alias=ali.name),
contains_eager('children.children', alias=ali2.name)).one()

Traceback (most recent call last):
  File "basic_tree.py", line 88, in <module>
    root = query.options(contains_eager('children', alias=ali.name),
contains_eager('children.children', alias=ali2.name)).one()
  File "/home/stephen/src/sqlalchemy/lib/sqlalchemy/orm/query.py",
line 267, in options
    opt.process_query(q)
  File "/home/stephen/src/sqlalchemy/lib/sqlalchemy/orm/interfaces.py",
line 561, in process_query
    self.process_query_property(query, paths)
  File "/home/stephen/src/sqlalchemy/lib/sqlalchemy/orm/strategies.py",
line 704, in process_query_property
    (mapper, propname) = paths[-1]
ValueError: too many values to unpack

and I get a different exception.

I'm a bit confused now, so please tell me if I've got something
fundamentally wrong here, otherwise are these bugs?

Thanks

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