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.

Reply via email to