]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- Improved the initialization logic of composite attributes such that
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 4 Feb 2014 00:13:16 +0000 (19:13 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 4 Feb 2014 00:13:16 +0000 (19:13 -0500)
calling ``MyClass.attribute`` will not require that the configure
mappers step has occurred, e.g. it will just work without throwing
any error. [ticket:2935]

doc/build/changelog/changelog_09.rst
lib/sqlalchemy/orm/descriptor_props.py
test/orm/test_composites.py

index bc711b89a0f55bed9826a53341ff440ec80be648..8e5fea1a7e3d98bf2ad4135b67e3313f576f7a4e 100644 (file)
     .. include:: changelog_07.rst
         :start-line: 5
 
+.. changelog::
+    :version: 0.9.3
+
+    .. change::
+        :tags: bug, orm
+        :tickets: 2935
+
+        Improved the initialization logic of composite attributes such that
+        calling ``MyClass.attribute`` will not require that the configure
+        mappers step has occurred, e.g. it will just work without throwing
+        any error.
+
 .. changelog::
     :version: 0.9.2
     :released: February 2, 2014
index 24b0a15e6aeb6f2ec3c26ab390379d17114e0456..9ecc9bb626012628648d38e5261c0d3f4cc3882e 100644 (file)
@@ -165,7 +165,6 @@ class CompositeProperty(DescriptorProperty):
         has been associated with its parent mapper.
 
         """
-        self._init_props()
         self._setup_arguments_on_columns()
 
     def _create_descriptor(self):
@@ -236,11 +235,12 @@ class CompositeProperty(DescriptorProperty):
             for prop in self.props
         ]
 
-    def _init_props(self):
-        self.props = props = []
+    @util.memoized_property
+    def props(self):
+        props = []
         for attr in self.attrs:
             if isinstance(attr, str):
-                prop = self.parent.get_property(attr)
+                prop = self.parent.get_property(attr, _configure_mappers=False)
             elif isinstance(attr, schema.Column):
                 prop = self.parent._columntoproperty[attr]
             elif isinstance(attr, attributes.InstrumentedAttribute):
@@ -251,6 +251,7 @@ class CompositeProperty(DescriptorProperty):
                         "attributes/attribute names as arguments, got: %r"
                         % (attr,))
             props.append(prop)
+        return props
 
     @property
     def columns(self):
index f13720ef38d010138b5e2d0f4e852a8adc221d83..8b777dcdf7e641726e1c2e9ef1a7001c78ce2332 100644 (file)
@@ -78,6 +78,12 @@ class PointTest(fixtures.MappedTest):
         sess.commit()
         return sess
 
+    def test_early_configure(self):
+        # test [ticket:2935], that we can call a composite
+        # expression before configure_mappers()
+        Edge = self.classes.Edge
+        Edge.start.__clause_element__()
+
     def test_round_trip(self):
         Graph, Point = self.classes.Graph, self.classes.Point
 
@@ -602,6 +608,13 @@ class ManyToOneTest(fixtures.MappedTest):
         })
         mapper(B, b)
 
+    def test_early_configure(self):
+        # test [ticket:2935], that we can call a composite
+        # expression before configure_mappers()
+        A = self.classes.A
+        A.c.__clause_element__()
+
+
     def test_persist(self):
         A, C, B = (self.classes.A,
                                 self.classes.C,