]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
move misplaced section
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 14 Oct 2020 22:18:13 +0000 (18:18 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 14 Oct 2020 22:18:13 +0000 (18:18 -0400)
Change-Id: I472049fbdda70da94bbf1cf7b5e10d04721bc771

doc/build/orm/cascades.rst
doc/build/orm/persistence_techniques.rst

index 528e69a97b506a6399264954ffb120c4237bbc6a..217692c73cf7b63dd3f08e63b25f8611f6a4a339 100644 (file)
@@ -603,3 +603,105 @@ course, :meth:`~.Session.add` ``i1`` to the session at a later point.   This
 option may be helpful for situations where an object needs to be kept out of a
 session until it's construction is completed, but still needs to be given
 associations to objects which are already persistent in the target session.
+
+
+
+.. _session_deleting_from_collections:
+
+Notes on Delete - Deleting Objects Referenced from Collections and Scalar Relationships
+----------------------------------------------------------------------------------------
+
+The ORM in general never modifies the contents of a collection or scalar
+relationship during the flush process.  This means, if your class has a
+:func:`_orm.relationship` that refers to a collection of objects, or a reference
+to a single object such as many-to-one, the contents of this attribute will
+not be modified when the flush process occurs.  Instead, it is expected
+that the :class:`.Session` would eventually be expired, either through the expire-on-commit behavior of
+:meth:`.Session.commit` or through explicit use of :meth:`.Session.expire`.
+At that point, any referenced object or collection associated with that
+:class:`.Session` will be cleared and will re-load itself upon next access.
+
+A common confusion that arises regarding this behavior involves the use of the
+:meth:`~.Session.delete` method.   When :meth:`.Session.delete` is invoked upon
+an object and the :class:`.Session` is flushed, the row is deleted from the
+database.  Rows that refer to the target row via  foreign key, assuming they
+are tracked using a :func:`_orm.relationship` between the two mapped object types,
+will also see their foreign key attributes UPDATED to null, or if delete
+cascade is set up, the related rows will be deleted as well. However, even
+though rows related to the deleted object might be themselves modified as well,
+**no changes occur to relationship-bound collections or object references on
+the objects** involved in the operation within the scope of the flush
+itself.   This means if the object was a
+member of a related collection, it will still be present on the Python side
+until that collection is expired.  Similarly, if the object were
+referenced via many-to-one or one-to-one from another object, that reference
+will remain present on that object until the object is expired as well.
+
+Below, we illustrate that after an ``Address`` object is marked
+for deletion, it's still present in the collection associated with the
+parent ``User``, even after a flush::
+
+    >>> address = user.addresses[1]
+    >>> session.delete(address)
+    >>> session.flush()
+    >>> address in user.addresses
+    True
+
+When the above session is committed, all attributes are expired.  The next
+access of ``user.addresses`` will re-load the collection, revealing the
+desired state::
+
+    >>> session.commit()
+    >>> address in user.addresses
+    False
+
+There is a recipe for intercepting :meth:`.Session.delete` and invoking this
+expiration automatically; see `ExpireRelationshipOnFKChange <http://www.sqlalchemy.org/trac/wiki/UsageRecipes/ExpireRelationshipOnFKChange>`_ for this.  However, the usual practice of
+deleting items within collections is to forego the usage of
+:meth:`~.Session.delete` directly, and instead use cascade behavior to
+automatically invoke the deletion as a result of removing the object from the
+parent collection.  The ``delete-orphan`` cascade accomplishes this, as
+illustrated in the example below::
+
+    class User(Base):
+        __tablename__ = 'user'
+
+        # ...
+
+        addresses = relationship(
+            "Address", cascade="all, delete-orphan")
+
+    # ...
+
+    del user.addresses[1]
+    session.flush()
+
+Where above, upon removing the ``Address`` object from the ``User.addresses``
+collection, the ``delete-orphan`` cascade has the effect of marking the ``Address``
+object for deletion in the same way as passing it to :meth:`~.Session.delete`.
+
+The ``delete-orphan`` cascade can also be applied to a many-to-one
+or one-to-one relationship, so that when an object is de-associated from its
+parent, it is also automatically marked for deletion.   Using ``delete-orphan``
+cascade on a many-to-one or one-to-one requires an additional flag
+:paramref:`_orm.relationship.single_parent` which invokes an assertion
+that this related object is not to shared with any other parent simultaneously::
+
+    class User(Base):
+        # ...
+
+        preference = relationship(
+            "Preference", cascade="all, delete-orphan",
+            single_parent=True)
+
+
+Above, if a hypothetical ``Preference`` object is removed from a ``User``,
+it will be deleted on flush::
+
+    some_user.preference = None
+    session.flush()  # will delete the Preference object
+
+.. seealso::
+
+    :ref:`unitofwork_cascades` for detail on cascades.
+
index 6e59924ccb17c4b0fadd040935c89de46122c110..93686889f98054090374c5d2c4ec461fde4e99c7 100644 (file)
@@ -2,105 +2,6 @@
 Additional Persistence Techniques
 =================================
 
-.. _session_deleting_from_collections:
-
-Notes on Delete - Deleting Objects Referenced from Collections and Scalar Relationships
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The ORM in general never modifies the contents of a collection or scalar
-relationship during the flush process.  This means, if your class has a
-:func:`_orm.relationship` that refers to a collection of objects, or a reference
-to a single object such as many-to-one, the contents of this attribute will
-not be modified when the flush process occurs.  Instead, it is expected
-that the :class:`.Session` would eventually be expired, either through the expire-on-commit behavior of
-:meth:`.Session.commit` or through explicit use of :meth:`.Session.expire`.
-At that point, any referenced object or collection associated with that
-:class:`.Session` will be cleared and will re-load itself upon next access.
-
-A common confusion that arises regarding this behavior involves the use of the
-:meth:`~.Session.delete` method.   When :meth:`.Session.delete` is invoked upon
-an object and the :class:`.Session` is flushed, the row is deleted from the
-database.  Rows that refer to the target row via  foreign key, assuming they
-are tracked using a :func:`_orm.relationship` between the two mapped object types,
-will also see their foreign key attributes UPDATED to null, or if delete
-cascade is set up, the related rows will be deleted as well. However, even
-though rows related to the deleted object might be themselves modified as well,
-**no changes occur to relationship-bound collections or object references on
-the objects** involved in the operation within the scope of the flush
-itself.   This means if the object was a
-member of a related collection, it will still be present on the Python side
-until that collection is expired.  Similarly, if the object were
-referenced via many-to-one or one-to-one from another object, that reference
-will remain present on that object until the object is expired as well.
-
-Below, we illustrate that after an ``Address`` object is marked
-for deletion, it's still present in the collection associated with the
-parent ``User``, even after a flush::
-
-    >>> address = user.addresses[1]
-    >>> session.delete(address)
-    >>> session.flush()
-    >>> address in user.addresses
-    True
-
-When the above session is committed, all attributes are expired.  The next
-access of ``user.addresses`` will re-load the collection, revealing the
-desired state::
-
-    >>> session.commit()
-    >>> address in user.addresses
-    False
-
-There is a recipe for intercepting :meth:`.Session.delete` and invoking this
-expiration automatically; see `ExpireRelationshipOnFKChange <http://www.sqlalchemy.org/trac/wiki/UsageRecipes/ExpireRelationshipOnFKChange>`_ for this.  However, the usual practice of
-deleting items within collections is to forego the usage of
-:meth:`~.Session.delete` directly, and instead use cascade behavior to
-automatically invoke the deletion as a result of removing the object from the
-parent collection.  The ``delete-orphan`` cascade accomplishes this, as
-illustrated in the example below::
-
-    class User(Base):
-        __tablename__ = 'user'
-
-        # ...
-
-        addresses = relationship(
-            "Address", cascade="all, delete-orphan")
-
-    # ...
-
-    del user.addresses[1]
-    session.flush()
-
-Where above, upon removing the ``Address`` object from the ``User.addresses``
-collection, the ``delete-orphan`` cascade has the effect of marking the ``Address``
-object for deletion in the same way as passing it to :meth:`~.Session.delete`.
-
-The ``delete-orphan`` cascade can also be applied to a many-to-one
-or one-to-one relationship, so that when an object is de-associated from its
-parent, it is also automatically marked for deletion.   Using ``delete-orphan``
-cascade on a many-to-one or one-to-one requires an additional flag
-:paramref:`_orm.relationship.single_parent` which invokes an assertion
-that this related object is not to shared with any other parent simultaneously::
-
-    class User(Base):
-        # ...
-
-        preference = relationship(
-            "Preference", cascade="all, delete-orphan",
-            single_parent=True)
-
-
-Above, if a hypothetical ``Preference`` object is removed from a ``User``,
-it will be deleted on flush::
-
-    some_user.preference = None
-    session.flush()  # will delete the Preference object
-
-.. seealso::
-
-    :ref:`unitofwork_cascades` for detail on cascades.
-
 
 
 .. _flush_embedded_sql_expressions: