summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2020-02-04 16:46:49 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2020-02-04 16:59:08 -0500
commit5d1eb327e6755917d6dbdcdc44bc56b4c97eaf0d (patch)
tree26fb8ed375c2e4b1c41096ff06c432ea28034e88
parent0e833e9116945ca39e78276af06e95725943ca05 (diff)
downloadsqlalchemy-5d1eb327e6755917d6dbdcdc44bc56b4c97eaf0d.tar.gz
Add second section detailing cascade_backrefs to backref section
We only have docs for "cascade_backrefs" in the session->cascades documentation, when this really should be mentioned in the chapter that's all about backrefs. Add a similar section and link to the original for further detail. Fixes: #5130 Change-Id: I58b6dcafd4ce43e4b9ebd86a40123502c01d4e39 (cherry picked from commit e48c685933b3b6f405134b5cb74f488075ae585d)
-rw-r--r--doc/build/orm/backref.rst51
1 files changed, 51 insertions, 0 deletions
diff --git a/doc/build/orm/backref.rst b/doc/build/orm/backref.rst
index 116fb74ee..b221e75e7 100644
--- a/doc/build/orm/backref.rst
+++ b/doc/build/orm/backref.rst
@@ -186,6 +186,57 @@ returned ``Address``. The :func:`.backref` function formatted the arguments we
it into a form that is interpreted by the receiving :func:`.relationship` as additional
arguments to be applied to the new relationship it creates.
+Setting cascade for backrefs
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A key behavior that occurs in the 1.x series of SQLAlchemy regarding backrefs
+is that :ref:`cascades <unitofwork_cascades>` will occur bidirectionally by
+default. This basically means, if one starts with an ``User`` object
+that's been persisted in the :class:`.Session`::
+
+ user = session.query(User).filter(User.id == 1).first()
+
+The above ``User`` is :term:`persistent` in the :class:`.Session`. It usually
+is intuitive that if we create an ``Address`` object and append to the
+``User.addresses`` collection, it is automatically added to the
+:class:`.Session` as in the example below::
+
+ user = session.query(User).filter(User.id == 1).first()
+ address = Address(email_address='foo')
+ user.addresses.append(address)
+
+The above behavior is known as the "save update cascade" and is described
+in the section :ref:`unitofwork_cascades`.
+
+However, if we instead created a new ``Address`` object, and associated the
+``User`` object with the ``Address`` as follows::
+
+ address = Address(email_address='foo', user=user)
+
+In the above example, it is **not** as intuitive that the ``Address`` would
+automatically be added to the :class:`.Session`. However, the backref behavior
+of ``Address.user`` indicates that the ``Address`` object is also appended to
+the ``User.addresses`` collection. This in turn intiates a **cascade**
+operation which indicates that this ``Address`` should be placed into the
+:class:`.Session` as a :term:`pending` object.
+
+Since this behavior has been identified as counter-intuitive to most people,
+it can be disabled by setting :paramref:`~.relationship.cascade_backrefs`
+to False, as in::
+
+
+ class User(Base):
+ # ...
+
+ addresses = relationship("Address", back_populates="user", cascade_backefs=False)
+
+See the example in :ref:`backref_cascade` for further information.
+
+.. seealso::
+
+ :ref:`backref_cascade`.
+
+
One Way Backrefs
~~~~~~~~~~~~~~~~