]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Rework synonym, synonym_for documentation
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 24 Jan 2018 23:03:04 +0000 (18:03 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 24 Jan 2018 23:03:58 +0000 (18:03 -0500)
The map_column example was incorrect, and overall the purpose
of this parameter as well as that of synonym_for was not explained;
examples added along with more encouragement to use hybrids.

Change-Id: I20bd286f541f798daa81fa598c0f31db1f5aa6ed
(cherry picked from commit 8250a4248fceaa3f4fbaebea3ff6a7f626299659)

lib/sqlalchemy/ext/declarative/api.py
lib/sqlalchemy/orm/descriptor_props.py

index 8d998b3b1d4cd26ff8d5db6c1a11532133b17cbf..d0746b2675844b564b65329dd578507e571c2c08 100644 (file)
@@ -69,21 +69,36 @@ class DeclarativeMeta(type):
 
 
 def synonym_for(name, map_column=False):
-    """Decorator, make a Python @property a query synonym for a column.
+    """Decorator that produces an :func:`.orm.synonym` attribute in conjunction
+    with a Python descriptor.
 
-    A decorator version of :func:`~sqlalchemy.orm.synonym`. The function being
-    decorated is the 'descriptor', otherwise passes its arguments through to
-    synonym()::
+    The function being decorated is passed to :func:`.orm.synonym` as the
+    :paramref:`.orm.synonym.descriptor` parameter::
 
-      @synonym_for('col')
-      @property
-      def prop(self):
-          return 'special sauce'
+        class MyClass(Base):
+            __tablename__ = 'my_table'
+
+            id = Column(Integer, primary_key=True)
+            _job_status = Column("job_status", String(50))
+
+            @synonym_for("job_status")
+            @property
+            def job_status(self):
+                return "Status: %s" % self._job_status
+
+    The :ref:`hybrid properties <mapper_hybrids>` feature of SQLAlchemy
+    is typically preferred instead of synonyms, which is a more legacy
+    feature.
+
+    .. seealso::
+
+        :ref:`synonyms` - Overview of synonyms
 
-    The regular ``synonym()`` is also usable directly in a declarative setting
-    and may be convenient for read/write properties::
+        :func:`.orm.synonym` - the mapper-level function
 
-      prop = synonym('col', descriptor=property(_read_prop, _write_prop))
+        :ref:`mapper_hybrids` - The Hybrid Attribute extension provides an
+        updated approach to augmenting attribute behavior more flexibly than
+        can be achieved with synonyms.
 
     """
     def decorate(fn):
index 5882da0c8a07afe2e52cd74ec8bef9574a79126d..449ae6e6a513dd3de0b3314b1009043850b48cf5 100644 (file)
@@ -503,8 +503,19 @@ class SynonymProperty(DescriptorProperty):
         in that the attribute will mirror the value and expression behavior
         of another attribute.
 
+        e.g.::
+
+            class MyClass(Base):
+                __tablename__ = 'my_table'
+
+                id = Column(Integer, primary_key=True)
+                job_status = Column(String(50))
+
+                status = synonym("job_status")
+
+
         :param name: the name of the existing mapped property.  This
-          can refer to the string name of any :class:`.MapperProperty`
+          can refer to the string name ORM-mapped attribute
           configured on the class, including column-bound attributes
           and relationships.
 
@@ -512,26 +523,48 @@ class SynonymProperty(DescriptorProperty):
           as a getter (and potentially a setter) when this attribute is
           accessed at the instance level.
 
-        :param map_column: if ``True``, the :func:`.synonym` construct will
-          locate the existing named :class:`.MapperProperty` based on the
-          attribute name of this :func:`.synonym`, and assign it to a new
-          attribute linked to the name of this :func:`.synonym`.
-          That is, given a mapping like::
+        :param map_column: **For classical mappings and mappings against
+          an existing Table object only**.  if ``True``, the :func:`.synonym`
+          construct will locate the existing named :class:`.MapperProperty`
+          based on the attribute name of this :func:`.synonym`, and assign it
+          to a new attribute linked to the name of this :func:`.synonym`.
+          This is intended to be used with the :paramref:`.synonym.descriptor`
+          parameter::
+
+            my_table = Table(
+                "my_table", metadata,
+                Column('id', Integer, primary_key=True),
+                Column('job_status', String(50))
+            )
+
+            class MyClass(object):
+                @property
+                def _job_status_descriptor(self):
+                    return "Status: %s" % self._job_status
 
-                class MyClass(Base):
-                    __tablename__ = 'my_table'
 
-                    id = Column(Integer, primary_key=True)
-                    job_status = Column(String(50))
+            mapper(
+                MyClass, my_table, properties={
+                    "job_status": synonym(
+                        "_job_status", map_column=True,
+                        descriptor=MyClass._job_status_descriptor)
+                }
+            )
 
-                    job_status = synonym("_job_status", map_column=True)
+          Above, the attribute named ``_job_status`` is automatically
+          mapped to the ``job_status`` column::
 
-          The above class ``MyClass`` will now have the ``job_status``
-          :class:`.Column` object mapped to the attribute named
-          ``_job_status``, and the attribute named ``job_status`` will refer
-          to the synonym itself.  This feature is typically used in
-          conjunction with the ``descriptor`` argument in order to link a
-          user-defined descriptor as a "wrapper" for an existing column.
+            >>> j1 = MyClass()
+            >>> j1._job_status = "employed"
+            >>> j1.job_status
+            Status: employed
+
+          When using Declarative, in order to provide a descriptor in
+          conjunction with a synonym, use the
+          :func:`sqlalchemy.ext.declarative.synonym_for` helper.  However,
+          note that the :ref:`hybrid properties <mapper_hybrids>` feature
+          should usually be preferred, particularly when redefining attribute
+          behavior.
 
         :param info: Optional data dictionary which will be populated into the
             :attr:`.InspectionAttr.info` attribute of this object.
@@ -551,10 +584,13 @@ class SynonymProperty(DescriptorProperty):
 
         .. seealso::
 
-            :ref:`synonyms` - examples of functionality.
+            :ref:`synonyms` - Overview of synonyms
+
+            :func:`.synonym_for` - a helper oriented towards Declarative
 
-            :ref:`mapper_hybrids` - Hybrids provide a better approach for
-            more complicated attribute-wrapping schemes than synonyms.
+            :ref:`mapper_hybrids` - The Hybrid Attribute extension provides an
+            updated approach to augmenting attribute behavior more flexibly
+            than can be achieved with synonyms.
 
         """
         super(SynonymProperty, self).__init__()