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.
