]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Use viewonly=True for composite secondary join example
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 19 Nov 2019 15:12:35 +0000 (10:12 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 19 Nov 2019 15:14:24 +0000 (10:14 -0500)
This example isn't writable as given.   Add additonal
warnings.  Also modernize the "query-enabled property"
section and add links to hybrids.

Fixes: #4992
Change-Id: I8f4b4db9e42ab2207a74532e3b17a56c35b0a837
(cherry picked from commit 25a6596030cbf16a870db142ddf096223c79be7a)

doc/build/orm/join_conditions.rst

index f54d2c04953fa1ede8f14ef9e756d524bbaefa62..c14a927c2629aa26a2a1a360bd92d062da7b2a69 100644 (file)
@@ -561,7 +561,10 @@ Composite "Secondary" Joins
 
 .. note::
 
-    This section features some new and experimental features of SQLAlchemy.
+    This section features far edge cases that are somewhat supported
+    by SQLAlchemy, however it is recommended to solve problems like these
+    in simpler ways whenever possible, by using reasonable relational
+    layouts and / or :ref:`in-Python attributes <mapper_hybrids>`.
 
 Sometimes, when one seeks to build a :func:`.relationship` between two tables
 there is a need for more than just two or three tables to be involved in
@@ -586,7 +589,8 @@ join condition (requires version 0.9.2 at least to function as is)::
                                 "join(C, C.d_id == D.id)",
                     primaryjoin="and_(A.b_id == B.id, A.id == C.a_id)",
                     secondaryjoin="D.id == B.d_id",
-                    uselist=False
+                    uselist=False,
+                    viewonly=True
                     )
 
     class B(Base):
@@ -628,11 +632,10 @@ tables while still keeping things "simple" for :func:`.relationship`, in that
 there's just "one" table on both the "left" and the "right" side; the
 complexity is kept within the middle.
 
-.. versionadded:: 0.9.2  Support is improved for allowing a :func:`.join()`
-   construct to be used directly as the target of the :paramref:`~.relationship.secondary`
-   argument, including support for joins, eager joins and lazy loading,
-   as well as support within declarative to specify complex conditions such
-   as joins involving class names as targets.
+.. warning:: A relationship like the above is typically marked as
+   ``viewonly=True`` and should be considered as read-only.  While there are
+   sometimes ways to make relationships like the above writable, this is
+   generally complicated and error prone.
 
 .. _relationship_non_primary_mapper:
 
@@ -784,6 +787,7 @@ Such a mapping would ordinarily also include a "plain" relationship
 from "A" to "B", for persistence operations as well as when the full
 set of "B" objects per "A" is desired.
 
+.. _query_enabled_properties:
 
 Building Query-Enabled Properties
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -802,7 +806,14 @@ conjunction with :class:`.Query` as follows:
         __tablename__ = 'user'
         id = Column(Integer, primary_key=True)
 
-        def _get_addresses(self):
+        @property
+        def addresses(self):
             return object_session(self).query(Address).with_parent(self).filter(...).all()
-        addresses = property(_get_addresses)
 
+In other cases, the descriptor can be built to make use of existing in-Python
+data.  See the section on :ref:`mapper_hybrids` for more general discussion
+of special Python attributes.
+
+.. seealso::
+
+    :ref:`mapper_hybrids`
\ No newline at end of file