summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2014-02-03 19:13:16 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2014-02-03 19:13:16 -0500
commitb069127b2d3f7b3f2c27f91cfcd32152a98c907f (patch)
tree3acd7c44c72d413c2aad2668be4fd5535a9f97ba
parent69a66d58c2d77fa52fe4f43456c5017eabe9502b (diff)
downloadsqlalchemy-b069127b2d3f7b3f2c27f91cfcd32152a98c907f.tar.gz
- 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]
-rw-r--r--doc/build/changelog/changelog_09.rst12
-rw-r--r--lib/sqlalchemy/orm/descriptor_props.py9
-rw-r--r--test/orm/test_composites.py13
3 files changed, 30 insertions, 4 deletions
diff --git a/doc/build/changelog/changelog_09.rst b/doc/build/changelog/changelog_09.rst
index bc711b89a..8e5fea1a7 100644
--- a/doc/build/changelog/changelog_09.rst
+++ b/doc/build/changelog/changelog_09.rst
@@ -12,6 +12,18 @@
: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 24b0a15e6..9ecc9bb62 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 f13720ef3..8b777dcdf 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,