On 01/07/2016 08:04 PM, Christopher Lee wrote:
> 
> I have a simple setup where I create two Nodes connected by an Edge,
> where the Edge should be eagerly loaded when the parent is loaded.  If I
> query the Node with a get(), it issues a select to refresh it, but then
> if I access its children, it issues a second get().  This behavior did
> not used to occur in 0.8.0.  If I expunge the session completely, then a
> get() will eagerly load the edges as expected.  Is that expected?  Did
> the mechanism by which get() repopulates the identity map change?

If I run this test in 0.8.0 I get the same behavior as that of master:

session.expire_all()
node = session.query(Node).get((1,))  # <-- Issues one select against
nodes with no outer join
print "-------------"
edges = node.children  # <-- Issues one select against edges with no
outer join


output at that part:

SELECT nodes.node_id AS nodes_node_id
FROM nodes
WHERE nodes.node_id = ?
2016-01-07 21:57:22,372 INFO sqlalchemy.engine.base.Engine (1,)
-------------
2016-01-07 21:57:22,373 INFO sqlalchemy.engine.base.Engine SELECT
edges.parent_id AS edges_parent_id, edges.child_id AS edges_child_id
FROM edges
WHERE ? = edges.parent_id ORDER BY edges.parent_id
2016-01-07 21:57:22,373 INFO sqlalchemy.engine.base.Engine (1,)


The select for edges is after the query, upon access to node.children.
I get this with 0.8.7, 0.8.0, latest 0.9, etc.

This is expected because the node of identity "1" is still present in
the identity map; the get() just emits a refresh of its row, and we
don't run eager loaders on "refresh".  There's a really ancient issue at
https://bitbucket.org/zzzeek/sqlalchemy/issues/1763/run-eager-loaders-on-unexpire
that proposes to change this but it's a big deal to mess around with
those mechanics.






> 
> 
> class Node(Base):
>     __tablename__ = "nodes"
>     node_id = sa.Column(sa.Integer, primary_key=True)
> 
> 
> class Edge(Base):
>     __tablename__ = 'edges'
>     parent_id = sa.Column(sa.Integer, sa.ForeignKey(Node.node_id),
> primary_key=True)
>     child_id = sa.Column(sa.Integer, sa.ForeignKey(Node.node_id),
> primary_key=True)
> 
> 
> Node.children = sa.orm.relationship(
>     Edge,
>     cascade="all, delete-orphan",
>     lazy=False,
>     uselist=True,
>     primaryjoin=Node.node_id==Edge.parent_id,
>     order_by=Edge.parent_id)
> 
> 
> engine = sa.create_engine('sqlite:///:memory:', echo=True)
> Base.metadata.create_all(engine)
> 
> Session = sa.orm.sessionmaker(bind=engine)
> session = Session()
> 
> n1 = Node(node_id=1)
> n2 = Node(node_id=2)
> 
> e12 = Edge(parent_id=n1.node_id, child_id=n2.node_id)
> 
> session.add_all([n1, n2, e12,])
> session.commit()
> 
> session.expire_all()
> node = session.query(Node).get((1,))  # <-- Issues one select against
> nodes with no outer join
> edges = node.children  # <-- Issues one select against edges with no
> outer join
> 
> Whereas if I expunge:
> 
> session.expunge_all()
> node = session.query(Node).get((1,))  # <-- Issues an outer join select
> against nodes and edges
> edges = node.children  # <-- No select statement, pulls from identity map
> 
> 
> -- 
> 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 https://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 https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to