summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES5
-rw-r--r--lib/sqlalchemy/orm/properties.py8
-rw-r--r--lib/sqlalchemy/sql/compiler.py2
-rw-r--r--test/orm/query.py8
4 files changed, 13 insertions, 10 deletions
diff --git a/CHANGES b/CHANGES
index a785ac1a9..e3ce282cf 100644
--- a/CHANGES
+++ b/CHANGES
@@ -33,6 +33,11 @@ CHANGES
version_id_col is typically set on the base mapper in an inheritance
relationship where it takes effect for all inheriting mappers.
[ticket:883]
+
+ - relaxed rules on column_property() expressions having labels; any
+ ColumnElement is accepted now, as the compiler auto-labels non-labeled
+ ColumnElements now. a selectable, like a select() statement, still
+ requires conversion to ColumnElement via as_scalar() or label().
- several ORM attributes have been removed or made private:
mapper.get_attr_by_column(), mapper.set_attr_by_column(),
diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py
index 806c91a2b..8980a4498 100644
--- a/lib/sqlalchemy/orm/properties.py
+++ b/lib/sqlalchemy/orm/properties.py
@@ -12,7 +12,7 @@ to handle flush-time dependency sorting and processing.
"""
from sqlalchemy import sql, schema, util, exceptions, logging
-from sqlalchemy.sql import util as sql_util, visitors, operators
+from sqlalchemy.sql import util as sql_util, visitors, operators, ColumnElement
from sqlalchemy.orm import mapper, sync, strategies, attributes, dependency
from sqlalchemy.orm import session as sessionlib
from sqlalchemy.orm import util as mapperutil
@@ -38,10 +38,8 @@ class ColumnProperty(StrategizedProperty):
self.comparator = ColumnProperty.ColumnComparator(self)
# sanity check
for col in columns:
- if not hasattr(col, 'name'):
- if hasattr(col, 'label'):
- raise ArgumentError('ColumnProperties must be named for the mapper to work with them. Try .label() to fix this')
- raise ArgumentError('%r is not a valid candidate for ColumnProperty' % col)
+ if not isinstance(col, ColumnElement):
+ raise ArgumentError('column_property() must be given a ColumnElement as its argument. Try .label() or .as_scalar() for Selectables to fix this.')
def create_strategy(self):
if self.deferred:
diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py
index 9b24dd521..d94d3fef6 100644
--- a/lib/sqlalchemy/sql/compiler.py
+++ b/lib/sqlalchemy/sql/compiler.py
@@ -438,7 +438,7 @@ class DefaultCompiler(engine.Compiled):
if isinstance(column, sql._Label):
return column
- if select.use_labels and column._label:
+ if select.use_labels and getattr(column, '_label', None):
return column.label(column._label)
if \
diff --git a/test/orm/query.py b/test/orm/query.py
index 562b1eee2..ef9e3540d 100644
--- a/test/orm/query.py
+++ b/test/orm/query.py
@@ -948,18 +948,18 @@ class ExternalColumnsTest(QueryTest):
clear_mappers()
try:
mapper(User, users, properties={
- 'concat': column_property(users.c.id * 2),
+ 'count': column_property(select([func.count(addresses.c.id)], users.c.id==addresses.c.user_id).correlate(users))
})
except exceptions.ArgumentError, e:
- assert str(e) == 'ColumnProperties must be named for the mapper to work with them. Try .label() to fix this'
+ assert str(e) == 'column_property() must be given a ColumnElement as its argument. Try .label() or .as_scalar() for Selectables to fix this.'
else:
raise 'expected ArgumentError'
def test_external_columns_good(self):
"""test querying mappings that reference external columns or selectables."""
mapper(User, users, properties={
- 'concat': column_property((users.c.id * 2).label('concat')),
- 'count': column_property(select([func.count(addresses.c.id)], users.c.id==addresses.c.user_id).correlate(users).label('count'))
+ 'concat': column_property((users.c.id * 2)),
+ 'count': column_property(select([func.count(addresses.c.id)], users.c.id==addresses.c.user_id).correlate(users).as_scalar())
})
mapper(Address, addresses, properties={