summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2022-10-28 12:20:22 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2022-10-28 12:20:22 -0400
commit654d941ce9c571de18aa09a09dc6cd90bf24734c (patch)
treefc8051bad84412b5bb8f15bc120b1a974512e4ac
parent2dc05f0c35f1b23168e65414d05ab275b0914f38 (diff)
downloadsqlalchemy-654d941ce9c571de18aa09a09dc6cd90bf24734c.tar.gz
update rel/fk FAQ entry
this entry still made the assumptions of behavior before ticket #3061, that accessing a non-initialized scalar attribute on a pending object would populate the attribute with None. It also used the word "initialize" when referring to a persistent object which is a misleading term, it's "loaded", even though in this example it's "loading" the value of None. Fix up the language to be more consistent with the #3061 change. Change-Id: I1abd8f1d2e9c44ebc9a29737ea270b338f104a3e
-rw-r--r--doc/build/faq/sessions.rst27
1 files changed, 17 insertions, 10 deletions
diff --git a/doc/build/faq/sessions.rst b/doc/build/faq/sessions.rst
index 79de9026b..a2c61c0a4 100644
--- a/doc/build/faq/sessions.rst
+++ b/doc/build/faq/sessions.rst
@@ -404,14 +404,21 @@ an "expire" event of the :func:`_orm.relationship` in which it's involved. This
that for the following sequence::
o = session.scalars(select(SomeClass).limit(1)).first()
- assert o.foo is None # accessing an un-set attribute sets it to None
+
+ # assume the existing o.foo_id value is None;
+ # accessing o.foo will reconcile this as ``None``, but will effectively
+ # "load" the value of None
+ assert o.foo is None
+
+ # now set foo_id to something. o.foo will not be immediately affected
o.foo_id = 7
-``o.foo`` is initialized to ``None`` when we first accessed it. Setting
-``o.foo_id = 7`` will have the value of "7" as pending, but no flush
+``o.foo`` is loaded with its effective database value of ``None`` when it
+is first accessed. Setting
+``o.foo_id = 7`` will have the value of "7" as a pending change, but no flush
has occurred - so ``o.foo`` is still ``None``::
- # attribute is already set to None, has not been
+ # attribute is already "loaded" as None, has not been
# reconciled with o.foo_id = 7 yet
assert o.foo is None
@@ -419,11 +426,12 @@ For ``o.foo`` to load based on the foreign key mutation is usually achieved
naturally after the commit, which both flushes the new foreign key value
and expires all state::
- Session.commit() # expires all attributes
+ session.commit() # expires all attributes
foo_7 = session.get(Foo, 7)
- assert o.foo is foo_7 # o.foo lazyloads on access
+ # o.foo will lazyload again, this time getting the new object
+ assert o.foo is foo_7
A more minimal operation is to expire the attribute individually - this can
be performed for any :term:`persistent` object using :meth:`.Session.expire`::
@@ -446,14 +454,13 @@ have meaning until the row is inserted; otherwise there is no row yet::
Session.add(new_obj)
- # accessing an un-set attribute sets it to None
+ # returns None but this is not a "lazyload", as the object is not
+ # persistent in the DB yet, and the None value is not part of the
+ # object's state
assert new_obj.foo is None
Session.flush() # emits INSERT
- # expire this because we already set .foo to None
- Session.expire(o, ["foo"])
-
assert new_obj.foo is foo_7 # now it loads
.. topic:: Attribute loading for non-persistent objects