From: Mike Bayer Date: Fri, 28 Oct 2022 16:20:22 +0000 (-0400) Subject: update rel/fk FAQ entry X-Git-Tag: rel_2_0_0b3~21 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=654d941ce9c571de18aa09a09dc6cd90bf24734c;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git 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 --- diff --git a/doc/build/faq/sessions.rst b/doc/build/faq/sessions.rst index 79de9026bc..a2c61c0a41 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