On Jul 7, 2011, at 7:04 PM, Ben Chess wrote:

> I've hit a problem where eagerload() fails to load in a relation of a
> relation when lazy='joined' is involved.  It's easiest just to show
> the test.  It fails in 0.7.1, and an equivalent test also fails in
> 0.6.8.
> 
> http://pastebin.com/ruq6SM1z
> 
> Basically, A has relations to B, C, and D.  C's relationship to A is a
> lazy='joined'.
> 
> First load A, eagerloading 'd_row'
> Then reference A.c_row, causing it to load C.
> 
> Then, separately, load C, eagerloading 'a_row.b_row'.
> At this point, I expunge_all() and demonstrate that b_row was not
> attached to C.a_row.
> 
> This does not occur if C's relationship to A is lazy='select'.
> Weirdly, this also does not occur if the initial load of A does not
> eagerload 'd_row'.   I'm not sure why that should affect anything.

This will make it pass:

assert 'a_row' in a_obj.c_rows[0].__dict__
session.expire_all()

c_obj = 
session.query(C).options(eagerload_all('a_row.b_row')).filter_by(id=1).one()
session.expunge_all()

assert c_obj.a_row.b_row

note after load #1, c_obj is already in the Session, and c_obj.a_row is already 
populated (looking in __dict__ is always the way to see if something is already 
loaded).    This is because of the lazy=False on C.a_row.

Then what happens in the load, and it occurs on line 2587 of mapper.py in the 
current tip, we get the C object already in the identity map during the second 
load.   We say, OK C do you have any attributes that aren't populated which we 
can pull from this row ?   C says, "nope".   C.a_row is already there.   This 
process currently doesn't descend further into the objects attached to C.a_row 
so the rest of the columns are thrown away.

It was actually somewhat of an innovation around 0.5 or so when I actually got 
the thing to populate "unloaded" attributes on objects that were otherwise 
loaded and might even have pending changes, which was a big step forward at 
that time, I didn't take on trying to figure out if eagers could keep on going 
into the graph and find deeper attributes that aren't loaded.   

If you have an opinion on this, let me know, right now I feel like its in an OK 
place considering the tradeoff of digging way down into a graph which may be 
unnecessary for those rows that were already loaded, many-to-ones are usually 
not an issue since they pull from the identity map.      If the issue is you're 
going for "detached" behavior, I generally don't recommend relying heavily on 
object graphs that are fully traversable in the detached state unless you're 
doing some kind of offline caching.   Of course, if there were a patch to that 
area of code that successfully kept the traversal going deeper into already 
loaded nodes based on the current eagers present, I'm open to evaluating it, 
though it doesn't seem like a quick tweak at the moment.

Nice test though, if you're interested in helping with tests/patches we're 
always looking for help.





> 
> -- 
> 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.
> 

-- 
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.

Reply via email to