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