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