On 11/24/2015 06:14 PM, Christopher Lee wrote: > > I am having a problem with SQLAlchemy 1.0.9 that cropped up when I > upgraded from 0.8.
this is a nicely written test but I get the same recursion overflow error when I run it in 0.8, 0.9, and 1.0, even back in 0.8.3. Can you provide a script that illustrates success in 0.8 and not in 1.0 ? thanks. > > I have the following polymorphic relationship defined. For some reason, > when I build a tree, and I try to access the children of the middle node > of the tree, it is picking up the wrong edge object and going into a > recursive loop. (Querying for the children of n2 is picking up the edge > e12, instead of the edges e23, e24 and e25.) > > Looking at the identity map, it looks like the query isn't populating > the correct objects. > > If I move the "links" relationship from the NodesWithEdges class to the > base Node class, the query works fine. Also, if I drop join_depth or > remove with with_polymorphic mapper arg, it forces multiple queries, and > the problem doesn't occur. Is this a bug with the new release, or am I > doing something bad? > > > from __future__ import print_function, unicode_literals > > import sqlalchemy as sa > import sqlalchemy.orm > import sqlalchemy.ext.associationproxy > import sqlalchemy.ext.declarative > import sqlalchemy.ext.orderinglist > > Base = sqlalchemy.ext.declarative.declarative_base() > > > class Node(Base): > __tablename__ = 'todo_elements' > > element_id = sa.Column(sa.Integer, nullable=False, primary_key=True) > element_type = sa.Column(sa.String(20), nullable=False) > > __mapper_args__ = { > 'polymorphic_on': element_type, > 'with_polymorphic': ('*', None), > } > > > class NodeWithEdges(Node): > __mapper_args__ = {'polymorphic_identity': 'todo.list'} > > > class LeafNode(Node): > __mapper_args__ = {'polymorphic_identity': 'todo.item'} > > my_flag = sa.Column(sa.Boolean, default=False) > > > class Edge(Base): > __tablename__ = 'todo_links' > __table_args__ = ( > sa.PrimaryKeyConstraint('parent_id', 'child_id'), > sa.ForeignKeyConstraint(['parent_id'], [Node.element_id]), > sa.ForeignKeyConstraint(['child_id'], [Node.element_id]), > ) > > parent_id = sa.Column(sa.Integer, nullable=False) > child_id = sa.Column(sa.Integer, nullable=False) > > > Edge.child = sa.orm.relationship( > Node, > uselist=False, > primaryjoin=Edge.child_id == Node.element_id, > lazy=False, > cascade='all', > passive_updates=False, > join_depth=8, > ) > > > NodeWithEdges.links = sa.orm.relationship( > Edge, > primaryjoin=NodeWithEdges.element_id == Edge.parent_id, > lazy=False, > cascade='all, delete-orphan', > single_parent=True, > passive_updates=False, > join_depth=8, > ) > > NodeWithEdges.children = sa.ext.associationproxy.association_proxy( > 'links', 'child', > creator=lambda child: Edge(child_id=child.element_id)) > > > > engine = sa.create_engine('sqlite:///:memory:', echo=True) > Base.metadata.create_all(engine) > > Session = sa.orm.sessionmaker(bind=engine) > session = Session() > > > # > # 1 --> 2 --> 3 > # --> 4 > # --> 5 > # > > n1 = NodeWithEdges(element_id=1) > n2 = NodeWithEdges(element_id=2) > n3 = LeafNode(element_id=3) > n4 = LeafNode(element_id=4, my_flag=True) > n5 = LeafNode(element_id=5) > > e12 = Edge(parent_id=n1.element_id, child_id=n2.element_id) > e23 = Edge(parent_id=n2.element_id, child_id=n3.element_id) > e24 = Edge(parent_id=n2.element_id, child_id=n4.element_id) > e25 = Edge(parent_id=n2.element_id, child_id=n5.element_id) > > session.add_all([n1, n2, n3, n4, n5, e12, e23, e24, e25]) > session.commit() > session.expunge_all() > > new_n1 = > session.query(NodeWithEdges).filter(NodeWithEdges.element_id==1).first() > print(session.identity_map.keys()) > > > def traverse(node, f, depth=0): > f(node, depth) > if hasattr(node, 'children'): > for c in node.children: > traverse(c, f, depth + 1) > > def indent_print(node, depth): > print(' ' * depth + str(node.element_id)) > if hasattr(node, 'my_flag'): > print(node.my_flag) > > traverse(new_n1, indent_print) > > -- > You received this message because you are subscribed to the Google > Groups "sqlalchemy" group. > To unsubscribe from this group and stop receiving emails from it, send > an email to sqlalchemy+unsubscr...@googlegroups.com > <mailto:sqlalchemy+unsubscr...@googlegroups.com>. > To post to this group, send email to sqlalchemy@googlegroups.com > <mailto:sqlalchemy@googlegroups.com>. > Visit this group at http://groups.google.com/group/sqlalchemy. > For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at http://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.