From 037db4cf9aedbc7eb5ec0a566a648cb842d2de31 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Thu, 23 Jun 2011 19:54:50 -0400 Subject: [PATCH] - the "cascade" section of the session doc was totally screwed up, mappings used the wrong form, example for cascade_backref used the wrong names. - rewrite relationship cascade_backrefs doc --- doc/build/orm/session.rst | 20 ++++++++++---------- lib/sqlalchemy/orm/__init__.py | 32 ++++++++++++++++++++++++-------- 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/doc/build/orm/session.rst b/doc/build/orm/session.rst index 74c4a9b3f2..d84c1d11a4 100644 --- a/doc/build/orm/session.rst +++ b/doc/build/orm/session.rst @@ -852,8 +852,8 @@ Cascading is configured by setting the ``cascade`` keyword argument on a :func:`~sqlalchemy.orm.relationship`:: mapper(Order, order_table, properties={ - 'items' : relationship(Item, items_table, cascade="all, delete-orphan"), - 'customer' : relationship(User, users_table, user_orders_table, cascade="save-update"), + 'items' : relationship(Item, cascade="all, delete-orphan"), + 'customer' : relationship(User, secondary=user_orders_table, cascade="save-update"), }) The above mapper specifies two relationships, ``items`` and ``customer``. The @@ -885,7 +885,7 @@ appropriate for one-to-one or one-to-many relationships. For a :func:`~sqlalchemy.orm.relationship` which establishes one-to-one via a local foreign key, i.e. a many-to-one that stores only a single parent, or one-to-one/one-to-many via a "secondary" (association) table, a warning will -be issued if ``delete-orphan`` is configured. To disable this warning, also +be issued if ``delete-orphan`` is configured. To disable this warning, specify the ``single_parent=True`` flag on the relationship, which constrains objects to allow attachment to only one parent at a time. @@ -896,11 +896,11 @@ The default value for ``cascade`` on :func:`~sqlalchemy.orm.relationship` is that, given a mapping such as this:: mapper(Order, order_table, properties={ - 'items' : relationship(Item, items_table, backref='order') + 'items' : relationship(Item, backref='order') }) If an ``Order`` is already in the session, and is assigned to the ``order`` -attribute of an ``Item``, the backref appends the ``Item`` to the ``orders`` +attribute of an ``Item``, the backref appends the ``Order`` to the ``items`` collection of that ``Order``, resulting in the ``save-update`` cascade taking place:: @@ -911,7 +911,7 @@ place:: >>> i1 = Item() >>> i1.order = o1 - >>> i1 in o1.orders + >>> i1 in o1.items True >>> i1 in session True @@ -919,13 +919,13 @@ place:: This behavior can be disabled as of 0.6.5 using the ``cascade_backrefs`` flag:: mapper(Order, order_table, properties={ - 'items' : relationship(Item, items_table, backref='order', + 'items' : relationship(Item, backref='order', cascade_backrefs=False) }) -So above, the assignment of ``i1.order = o1`` will append ``i1`` to the ``orders`` -collection of ``o1``, but will not add ``i1`` to the session. You can of -course :func:`~.Session.add` ``i1`` to the session at a later point. This option +So above, the assignment of ``i1.order = o1`` will append ``i1`` to the ``items`` +collection of ``o1``, but will not add ``i1`` to the session. You can, of +course, :func:`~.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. diff --git a/lib/sqlalchemy/orm/__init__.py b/lib/sqlalchemy/orm/__init__.py index 03612ac47a..854aa8cee5 100644 --- a/lib/sqlalchemy/orm/__init__.py +++ b/lib/sqlalchemy/orm/__init__.py @@ -266,14 +266,30 @@ def relationship(argument, secondary=None, **kwargs): :param cascade_backrefs=True: a boolean value indicating if the ``save-update`` cascade should - operate along a backref event. When set to ``False`` on a - one-to-many relationship that has a many-to-one backref, assigning - a persistent object to the many-to-one attribute on a transient object - will not add the transient to the session. Similarly, when - set to ``False`` on a many-to-one relationship that has a one-to-many - backref, appending a persistent object to the one-to-many collection - on a transient object will not add the transient to the session. - + operate along an assignment event intercepted by a backref. + When set to ``False``, + the attribute managed by this relationship will not cascade + an incoming transient object into the session of a + persistent parent, if the event is received via backref. + + That is:: + + mapper(A, a_table, properties={ + 'bs':relationship(B, backref="a", cascade_backrefs=False) + }) + + If an ``A()`` is present in the session, assigning it to + the "a" attribute on a transient ``B()`` will not place + the ``B()`` into the session. To set the flag in the other + direction, i.e. so that ``A().bs.append(B())`` won't add + a transient ``A()`` into the session for a persistent ``B()``:: + + mapper(A, a_table, properties={ + 'bs':relationship(B, + backref=backref("a", cascade_backrefs=False) + ) + }) + ``cascade_backrefs`` is new in 0.6.5. :param collection_class: -- 2.39.5