As always, thank you for the quick reply, Mike!

On Sat, Apr 14, 2012 at 06:34:10PM -0400, Michael Bayer wrote:
> 
> On Apr 14, 2012, at 5:38 PM, Jeff Dairiki wrote:
> 
> > I have a one-to-one relationship to a table in a different database
> > which I'd like to, effectively, eager-load.  Lazy='joined' and
> > lazy='subquery' won't work, since they rely an impossible JOIN between
> > tables in two different databases.
> > 
> > Lazy='immediate' works, but results in one query per instance.  If I
> > have a one-to-one relationship between A and B, and execute a query
> > which loads 100 A's, there will be 100 more queries which each load
> > one B.  What I'd like is to have two queries total: one to load the As
> > and a second to load the Bs.
> > 
> > I've been able to do this manually by doing something like this:
> > 
> >   # Do some query
> >   parents = session.query(Parent).filter(some_condition).all()
> > 
> >   # "Eager load" 
> >   ids = [ parent.id for parent in parents
> >           if 'child' in instance_state(parent).unloaded ]
> >   get_parent = session.query(Parent).get
> >   for child in session.query(Child).filter(Child.parent_id.in_(ids)):
> >       parent = get_parent(child.parent_id)
> >       set_committed_value(child, 'parent', parent)
> >       set_committed_value(parent, 'child', child)
> > 
> > Is there a good way to do this more automatically?
> 
> I don't have a spectacular suggestion at the moment, if you've
> looked at how the subquery/immediate loading schemes work, the first
> row we get for the "parent" triggers the load of all the "child"
> objects, which is a product of the loader strategy system for that
> particular attribute.  The mechanics here would need to do
> everything entirely after the full parent collection is loaded.

I did dig far enough to figure that out.  I was sort of
expecting/hoping to find an event I could listen for, but alas.

> I'd probably keep it simple and just do what you're doing, just
> either inside of a helper function like
> iterate_with_related(myquery, "children")

Will do.  Actually, I'm already doing roughly that.  It works fine,
it's just that one must remember to invoke the helper function.

> or perhaps do a subclass of Query.

I thought of that, bug it felt somehow wrong to customize behavior for
a specific mapped attribute by specializing Query.

> As far as the actual load operation, there's a recipe for this kind
> of operation at
> http://www.sqlalchemy.org/trac/wiki/UsageRecipes/DisjointEagerLoading
> which will do things a little more directly, without the need for
> query.get().  There's a "generalized" recipe there too which you can
> probably adapt to what you're doing here.

Aha.  Yes, that helps a bit.

Thanks again!
Jeff

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to [email protected].
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