On Dec 15, 2:39 pm, Michael Bayer <[email protected]> wrote:
> On Dec 15, 2011, at 2:13 PM, Kent wrote:
> > On 12/15/2011 1:31 PM, Michael Bayer wrote:
> >> Are there reasons one need to avoid referencing unloaded relationships 
> >> from within before_upate()?  (I can't recall the exact problem I've had in 
> >> the past with that at the moment.)
>
> > Thanks for all the input.  Regarding the issue of referencing a 
> > relationship from within before_update()/before_insert(), etc. I looked up 
> > my previous problem and it is related to this code from strategies.py:
>
> > class LazyLoader()
> > ...
> > def _load_for_state(self, state, passive):
> > ...
> >        if self.use_get:
> >            if session._flushing:
> >                get_attr = 
> > instance_mapper._get_committed_state_attr_by_column
> >            else:
> >                get_attr = instance_mapper._get_state_attr_by_column
>
> > If we are in the middle of a flush, we don't attempt a query but rather use 
> > the committed state.  This caused me problems when the committed state of 
> > the relationship was "None" (for example, not loaded yet?)
>
> > For my own understanding, what implications does this have?  It kind of 
> > freaked me out because I interpreted that as meaning "I'm not sure if I can 
> > rely upon unloaded relationships at all from within these mid-flush event 
> > methods..." because I certainly don't want to be using stale, old data.  Is 
> > there a threat of this, or only of it sometimes being "None"?
>
> so this is we're inside of a flush, and suppose we need to get at 
> someobject.some_related specifically to target what's present in the database 
> - if you've changed the value of someobject.some_related_id, that isn't 
> flushed yet - we need some_related relative to the some_related_id that was 
> loaded from the database.
>

wait...that's where you lose me.  In this condition where user's
changed someobject.some_related_id, then as soon as that is flushed,
someobject.some_related by definition is no longer going to be the
object we get with the currently committed id.... This is circling
back to the automatic expiration of relationships dilemma.  it seems
we are purposefully giving them the wrong object.  Directly after the
flush, were we to query that same relationship, it would return a
different object/collection.

I believe that is the other reason I needed to abandon trusting the
relationship when within a flush.  I think I recall this exact problem
occurring to me.  The id had changed and anywhere else within
SQLAlchemy land (that isn't in a flush), I could trust the
relationship to bring back the correct object given the current state
of the id.  However, in that case (inside a flush) it was bringing
back the wrong object (the one inconsistent with the current id) so
inspecting that related object's values would give me the wrong
answer.

You sure this logic (and therefore also test cases) aren't wrong?


> There's still potentially a query run to get at some_related, just the 
> foreign key value we use from the parent is different - it's looking at the 
> persistent value.
>
> To get more specific, comment out the conditional and just make it do the 
> non-committed, then run the orm unit tests.  The tests that fail will be the 
> ones that illustrate the use case.

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

Reply via email to