On Jan 9, 2012, at 8:56 PM, Jimmy Yuen Ho Wong wrote: >> In the subqueryload_all()/subqueryload() example, you'll note the second one >> with two separate subqueryload() calls does in fact correctly do the >> "subqueryload" twice. There's no way SQLA would ever "figure out" >> automatically that they're against the same table and then join the two >> queries together, decisionmaking like would be enormously complicated as >> well as the mechanics of how to get a single loader to coordinate among two >> relationships. If you use just one relationship() to SearchOption then >> provide filtered accessors, then you get exactly the optimization you're >> looking for. > Is it possible to include a special flag to the subqueryload() call to > tell SA to optimize for this case?
it's not even the decision itself that is most challenging here, it's the implementation, as well as API clutter. Routing the loader into two collections within the internals would be a giant knot of almost never used code, right in the core of the ORM, for a flag that nobody ever uses or knows about. The event system is how things like this should be done - the event I gave you is a starter. There's likely ways to get some other event hooks in there as well, there's a hook called "append_result" that actually should be working here but it wasn't doing it when I tried. > SA already knows about the class > hierarchy to be able to distinguish between the classes and how they map > to the rows returned, changing the model mapping is not always feasible. > In fact, if SA could do this, subqueryload() will be the optimal > solution for this use case. joinedload(), even when it works, it's still > too wasteful. Using events will work for now, but it's not as obvious. I disagree - a flag would be unused, opaque, arbitrary. This is not in any way an obvious or common use case - I've never seen it before. A ten line event handler OTOH illustrates exactly what's going on and keeps the core simple. We've had many weird "flag" based features in the past and the work they bring is to take them *out*, and replace them with an open ended and user-centric approach. Examples include: "entity name", "mutable=True", implicit order by, "polymorphic_fetch", Session.load(), all kinds of crap. removing bad API is 10x harder than adding it. We don't do it except for features that are of widespread use or are very simple and don't complicate the core, like event hooks. >> Ticket 2120 calls for at least an option "nested_joins=True", specifying >> that the more correct/efficient system of nesting joins should be used. >> This is all 0.8 stuff, as the joined eager loading code would be >> destabilized by this - if it turns out to be an isolated option it could >> move to 0.7. Your set of tests here makes me more interested in the issue >> though so perhaps we'll see if I have time to try some things out. > Does it mean that the only way to eager load reliably in this > many-to-many single table inheritance use case, depending on the data, > is joinedload(innerjoin=True) for uselist=False relationships for now? > In my case, I can just use innerjoin=True all the way, but there may be > cases where the code has to switch between innerjoin and left join > depending on the relationships. joinedload() writes out flattened joins so whatever limitations are apparent there, yes. -- 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.
