> > Thanks a lot for the tips on how to approach this problem. That's > > exactly what I needed. > > in 0.4 you'd get it off the impl (0.5 too, this is just uglier API):
Excellent! Here's what I came up with as an initial solution: def poly_load(parent, collection, path): def itersiblings(parent, path): def iteritems(items, attr): for item in items: for child in getattr(item, attr): yield child items = [parent] while path: items = iteritems(items, path.pop(0)) return items path = path.split(".") assert len(path) % 2 == 0, "path must contain an even number of elements" mid = len(path) / 2 gparent = parent for attr in path[:mid]: gparent = getattr(gparent, attr) session = sqlalchemy.orm.session.object_session(parent) backref = getattr(type(parent), collection).property.backref.key itemclass = getattr(type(parent), collection).property.mapper.class_ qry = session.query(itemclass) \ .join([backref] + path[:mid]) \ .filter(type(gparent).table.c.id == gparent.id) groups = defaultdict(list) for item in qry: groups[getattr(item, backref).id].append(item) impl = getattr(type(parent), collection).impl for sibling in itersiblings(gparent, path[mid:]): if sibling.id in groups: impl.set_committed_value(sibling._state, groups.get (sibling.id)) Example usage: # prepare for takeoff order = session.get(Order, 123) item = order.items[0] # triggers lazy load # sit back and watch the fireworks! poly_load(item, "attributes", "order.items") # BOOM loaded all attributes of all items poly_load(item, "tags", "order.items") # BOOM loaded all tags of all items poly_load(item.tags[0], "bars", "item.order.items.tags") # BOOOM loaded all bars of all tags of all items Some assumptions I was able to make that kept it simple: - All mapped classes in my model have a 'table' attribute - All entities in my model have an 'id' attribute, which is the primary key. - Relationships traversed by this loader are configured with the necessary backrefs to make it work. Initial tests seem to show a DRAMATIC performance improvement. Thanks a lot for your help Mike. Next up, roll this into a loader strategy so I can configure it on the mapper and have it all happen automatically. ~ Daniel --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~----------~----~----~----~------~----~------~--~---