diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2007-09-24 19:27:52 +0000 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2007-09-24 19:27:52 +0000 |
| commit | a0838e0c476f7deab5b67f431c8ce107974b9313 (patch) | |
| tree | 5a990b0a2f87f142bf96c75fa7c2597198f887f7 /lib/sqlalchemy | |
| parent | 6b5543995b66b524097ad540a0a3f9dfd9eb9413 (diff) | |
| download | sqlalchemy-a0838e0c476f7deab5b67f431c8ce107974b9313.tar.gz | |
- columns from Alias objects, when used to target result-row columns, must match exactly
to the label used in the generated statement. This is so searching for columns in a
result row which match aliases won't accidentally match non-aliased columns.
fixes errors which can arise in eager loading scenarios.
Diffstat (limited to 'lib/sqlalchemy')
| -rw-r--r-- | lib/sqlalchemy/engine/base.py | 17 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/strategies.py | 4 | ||||
| -rw-r--r-- | lib/sqlalchemy/sql/expression.py | 8 |
3 files changed, 25 insertions, 4 deletions
diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py index cc2ea6d5d..7e9d57d97 100644 --- a/lib/sqlalchemy/engine/base.py +++ b/lib/sqlalchemy/engine/base.py @@ -1287,10 +1287,19 @@ class ResultProxy(object): elif isinstance(key, basestring) and key.lower() in props: rec = props[key.lower()] elif isinstance(key, expression.ColumnElement): - label = context.column_labels.get(key._label, key.name).lower() - if label in props: - rec = props[label] - + try: + if getattr(key, '_exact_match', False): + # exact match flag means the label must be present in the + # generated column_labels + label = context.column_labels[key._label].lower() + else: + # otherwise, fall back to the straight name of the column + # if not in generated labels + label = context.column_labels.get(key._label, key.name).lower() + if label in props: + rec = props[label] + except KeyError: + pass if not "rec" in locals(): raise exceptions.NoSuchColumnError("Could not locate column in row for column '%s'" % (str(key))) diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py index 8016673ff..f3a0029f5 100644 --- a/lib/sqlalchemy/orm/strategies.py +++ b/lib/sqlalchemy/orm/strategies.py @@ -615,6 +615,10 @@ class EagerLoader(AbstractRelationLoader): selectcontext.stack.pop() selectcontext.stack.pop() + + if self._should_log_debug: + self.logger.debug("Returning eager instance loader for %s" % str(self)) + return (execute, execute, None) else: if self._should_log_debug: diff --git a/lib/sqlalchemy/sql/expression.py b/lib/sqlalchemy/sql/expression.py index f7514fec9..dac5d7a74 100644 --- a/lib/sqlalchemy/sql/expression.py +++ b/lib/sqlalchemy/sql/expression.py @@ -2423,6 +2423,14 @@ class Alias(FromClause): def _get_from_objects(self, **modifiers): return [self] + def _proxy_column(self, column): + c = column._make_proxy(self) + # send a note to ResultProxy to not "approximate" + # this column based on its name when targeting result columns + # see test/sql/query.py QueryTest.test_exact_match + c._exact_match = True + return c + bind = property(lambda s: s.selectable.bind) class _ColumnElementAdapter(ColumnElement): |
