On Jan 5, 2010, at 12:06 PM, boothead wrote:

> Hi All,
> 
> I've got a fairly complicated object structure for which I'm building
> a tree type object. The first level of the tree is a polymorphic
> relation with three subclasses. Two of those subclasses are fairly
> straightforward, but the 3rd points to another class with subclasses.
> I would like to be able to query this 3rd type of object and have the
> different types of object returned from the query be prepopulated with
> their various different attributes so that I can do:
> 
> row1.object.attribute1
> row2.object.some_other_attribute
> 
> In the above cases 'object' will be one of several different
> subclasses so that attribute1 and some_other_attribute don't exist on
> both subclasses. I'd like for this attribute access to not hit the
> database as far as possible. So I'm, basically looking for a way to
> load the whole object graph from the parent in one hit.

its significant if you're using joined table or single table inheritance for 
the inheritances.   Single produces better results for loading as you save on a 
lot of additional joins.

I'll try to indicate the various approaches here, in ascending order of 
tediousness.

Usually you set up the eagerloads at querytime using the eagerload and 
eagerload_all() options.   If these are not allowing you to descend into the 
"conditional" attributes, you can try using outerjoin() explicitly in 
conjunction with contains_eager() (you can look up an example in the mapping 
docs).

So if there's really a lot of joined table inheritance making it impossible, I 
will actually use several queries, one for the primary objects, and another (or 
more) for the "secondary" objects which relates back to the primary rows using 
in_(ids) or in_(subquery representing the original result).   Once you load 
those, theres three scenarios for associating them with the parents.  if the 
parents relate to the child objects using a straight many-to-one, no further 
action is needed - when you access the m2o attribute, the lazyloader will use a 
"get" from the session to load them.  What you should do though is maintain a 
reference to the collection of "secondary" objects and then hit all those 
attributes on the parents so that the association occurs, and the secondary 
objects arent lost to garbage collection.   the second scenario is if the 
parents reference a collection - if they already have a collection of objects, 
but only the "base" table was loaded, the "joined" attributes are populated 
automaticaly by fully loading those secondary rows.   Otherwise, if you truly 
want to load new objects and manually attach them to parent collections, you 
can use the attributes.set_commited_value() function to associate objects and 
collections together, in the same manner as they do when loaded.


> 
> I've tried various flavours of eagerload join and outerjoin on the
> query, but I'm not even sure if I'm on the right track or not. At this
> stage I'm just looking for general pointers so I haven't put up any
> code for the classes and mappers concerned, if it would help I could
> try and distil what I've got into something illustrative.
> 
> TIA
> Ben
> -- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To post to this group, send email to sqlalch...@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.
> 
> 

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


Reply via email to