diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-10-15 20:07:13 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-10-15 20:07:13 -0400 |
| commit | 2484ef34c27f3342e62bd6285bb3668e2c913090 (patch) | |
| tree | e7e329fb3e06e903c793f6944a1facd72b0bd4ef /lib/sqlalchemy/orm/query.py | |
| parent | af3c8a75c8e9eba593f6568187226548f1b8735d (diff) | |
| download | sqlalchemy-2484ef34c27f3342e62bd6285bb3668e2c913090.tar.gz | |
- [feature] The Query can now load entity/scalar-mixed
"tuple" rows that contain
types which aren't hashable, by setting the flag
"hashable=False" on the corresponding TypeEngine object
in use. Custom types that return unhashable types
(typically lists) can set this flag to False.
[ticket:2592]
- [bug] Applying a column expression to a select
statement using a label with or without other
modifying constructs will no longer "target" that
expression to the underlying Column; this affects
ORM operations that rely upon Column targeting
in order to retrieve results. That is, a query
like query(User.id, User.id.label('foo')) will now
track the value of each "User.id" expression separately
instead of munging them together. It is not expected
that any users will be impacted by this; however,
a usage that uses select() in conjunction with
query.from_statement() and attempts to load fully
composed ORM entities may not function as expected
if the select() named Column objects with arbitrary
.label() names, as these will no longer target to
the Column objects mapped by that entity.
[ticket:2591]
Diffstat (limited to 'lib/sqlalchemy/orm/query.py')
| -rw-r--r-- | lib/sqlalchemy/orm/query.py | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index 35d32651f..a6d20a973 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -29,7 +29,8 @@ from .util import ( _is_aliased_class, _is_mapped_class, _orm_columns, join as orm_join,with_parent, aliased ) -from .. import sql, util, log, exc as sa_exc, inspect, inspection +from .. import sql, util, log, exc as sa_exc, inspect, inspection, \ + types as sqltypes from ..sql.expression import _interpret_as_from from ..sql import ( util as sql_util, @@ -2930,12 +2931,20 @@ class _ColumnEntity(_QueryEntity): if c is not column: return + if not isinstance(column, sql.ColumnElement): raise sa_exc.InvalidRequestError( "SQL expression, column, or mapped entity " "expected - got '%r'" % (column, ) ) + type_ = column.type + if type_.hashable: + self.filter_fn = lambda item: item + else: + counter = util.counter() + self.filter_fn = lambda item: counter() + # If the Column is unnamed, give it a # label() so that mutable column expressions # can be located in the result even @@ -2972,6 +2981,7 @@ class _ColumnEntity(_QueryEntity): else: self.entity_zero = None + @property def entity_zero_or_selectable(self): if self.entity_zero is not None: @@ -2985,8 +2995,6 @@ class _ColumnEntity(_QueryEntity): def type(self): return self.column.type - def filter_fn(self, item): - return item def adapt_to_selectable(self, query, sel): c = _ColumnEntity(query, sel.corresponding_column(self.column)) |
