summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2013-12-12 13:30:16 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2013-12-12 13:30:16 -0500
commitf244287f46476f3b111a2495ce4207530f4b51d8 (patch)
tree0c3fe6631e429774fbe5856f4816d8ade9640519
parentace7bdbc78571619cb103d57a188fbe6aa92b627 (diff)
downloadsqlalchemy-f244287f46476f3b111a2495ce4207530f4b51d8.tar.gz
- :func:`.composite` will raise an informative error message when the
columns/attribute (names) passed don't resolve to a Column or mapped attribute (such as an erroneous tuple); previously raised an unbound local. [ticket:2889]
-rw-r--r--doc/build/changelog/changelog_08.rst10
-rw-r--r--lib/sqlalchemy/orm/descriptor_props.py5
-rw-r--r--test/orm/test_composites.py20
3 files changed, 34 insertions, 1 deletions
diff --git a/doc/build/changelog/changelog_08.rst b/doc/build/changelog/changelog_08.rst
index 2cd9b5855..2e1bdc9ad 100644
--- a/doc/build/changelog/changelog_08.rst
+++ b/doc/build/changelog/changelog_08.rst
@@ -12,6 +12,16 @@
:version: 0.8.5
.. change::
+ :tags: bug, orm
+ :versions: 0.9.0b2
+ :tickets: 2889
+
+ :func:`.composite` will raise an informative error message when the
+ columns/attribute (names) passed don't resolve to a Column or mapped
+ attribute (such as an erroneous tuple); previously raised an unbound
+ local.
+
+ .. change::
:tags: bug, declarative
:versions: 0.9.0b2
:tickets: 2888
diff --git a/lib/sqlalchemy/orm/descriptor_props.py b/lib/sqlalchemy/orm/descriptor_props.py
index 1156a140e..231e531e4 100644
--- a/lib/sqlalchemy/orm/descriptor_props.py
+++ b/lib/sqlalchemy/orm/descriptor_props.py
@@ -245,6 +245,11 @@ class CompositeProperty(DescriptorProperty):
prop = self.parent._columntoproperty[attr]
elif isinstance(attr, attributes.InstrumentedAttribute):
prop = attr.property
+ else:
+ raise sa_exc.ArgumentError(
+ "Composite expects Column or Column-bound "
+ "attributes/attribute names as arguments, got: %r"
+ % (attr,))
props.append(prop)
@property
diff --git a/test/orm/test_composites.py b/test/orm/test_composites.py
index b4abb2dce..8946b6908 100644
--- a/test/orm/test_composites.py
+++ b/test/orm/test_composites.py
@@ -6,7 +6,7 @@ from sqlalchemy import Integer, String, ForeignKey, \
from sqlalchemy.testing.schema import Table, Column
from sqlalchemy.orm import mapper, relationship, \
CompositeProperty, aliased
-from sqlalchemy.orm import composite, Session
+from sqlalchemy.orm import composite, Session, configure_mappers
from sqlalchemy.testing import eq_
from sqlalchemy.testing import fixtures
@@ -739,6 +739,24 @@ class ConfigurationTest(fixtures.MappedTest):
})
self._test_roundtrip()
+ def test_check_prop_type(self):
+ edge, Edge, Point = (self.tables.edge,
+ self.classes.Edge,
+ self.classes.Point)
+ mapper(Edge, edge, properties={
+ 'start': sa.orm.composite(Point, (edge.c.x1,), edge.c.y1),
+ })
+ assert_raises_message(
+ sa.exc.ArgumentError,
+ # note that we also are checking that the tuple
+ # renders here, so the "%" operator in the string needs to
+ # apply the tuple also
+ r"Composite expects Column or Column-bound "
+ "attributes/attribute names as "
+ "arguments, got: \(Column",
+ configure_mappers
+ )
+
class ComparatorTest(fixtures.MappedTest, testing.AssertsCompiledSQL):
__dialect__ = 'default'