From: Mike Bayer Date: Tue, 4 Feb 2014 00:13:16 +0000 (-0500) Subject: - Improved the initialization logic of composite attributes such that X-Git-Tag: rel_0_9_3~54 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b069127b2d3f7b3f2c27f91cfcd32152a98c907f;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - 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. [ticket:2935] --- diff --git a/doc/build/changelog/changelog_09.rst b/doc/build/changelog/changelog_09.rst index bc711b89a0..8e5fea1a7e 100644 --- a/doc/build/changelog/changelog_09.rst +++ b/doc/build/changelog/changelog_09.rst @@ -11,6 +11,18 @@ .. 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 diff --git a/lib/sqlalchemy/orm/descriptor_props.py b/lib/sqlalchemy/orm/descriptor_props.py index 24b0a15e6a..9ecc9bb626 100644 --- a/lib/sqlalchemy/orm/descriptor_props.py +++ b/lib/sqlalchemy/orm/descriptor_props.py @@ -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): diff --git a/test/orm/test_composites.py b/test/orm/test_composites.py index f13720ef38..8b777dcdf7 100644 --- a/test/orm/test_composites.py +++ b/test/orm/test_composites.py @@ -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,