From 73f1c6044552a652f6ae87ab0b93e28b1e54f4a6 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Tue, 23 Jan 2007 18:45:11 +0000 Subject: [PATCH] - added support for column "key" attribute to be useable in row[]/row. --- CHANGES | 1 + lib/sqlalchemy/ansisql.py | 4 ++++ lib/sqlalchemy/engine/base.py | 22 +++++++++++++++++----- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index 6a38f16569..9ea810c6de 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,7 @@ non-ambiguous. - sql: - added "fetchmany()" support to ResultProxy + - added support for column "key" attribute to be useable in row[]/row. - changed "BooleanExpression" to subclass from "BinaryExpression", so that boolean expressions can also follow column-clause behaviors (i.e. label(), etc). - trailing underscores are trimmed from func. calls, such as func.if_() diff --git a/lib/sqlalchemy/ansisql.py b/lib/sqlalchemy/ansisql.py index 6376ea7481..69b082e414 100644 --- a/lib/sqlalchemy/ansisql.py +++ b/lib/sqlalchemy/ansisql.py @@ -99,6 +99,9 @@ class ANSICompiler(sql.Compiled): # which will be passed to a ResultProxy and used for resultset-level value conversion self.typemap = {} + # a dictionary of select columns mapped to their name or key + self.columns = {} + # True if this compiled represents an INSERT self.isinsert = False @@ -207,6 +210,7 @@ class ANSICompiler(sql.Compiled): # if we are within a visit to a Select, set up the "typemap" # for this column which is used to translate result set values self.typemap.setdefault(column.name.lower(), column.type) + self.columns.setdefault(column.key, column) if column.table is None or not column.table.named_with_column(): self.strings[column] = self.preparer.format_column(column) else: diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py index 65f2b5586b..77ab866c71 100644 --- a/lib/sqlalchemy/engine/base.py +++ b/lib/sqlalchemy/engine/base.py @@ -297,7 +297,7 @@ class Connection(Connectable): context.pre_exec(self.__engine, proxy, compiled, parameters) proxy(str(compiled), parameters) context.post_exec(self.__engine, proxy, compiled, parameters) - return ResultProxy(self.__engine, self, cursor, context, typemap=compiled.typemap) + return ResultProxy(self.__engine, self, cursor, context, typemap=compiled.typemap, columns=compiled.columns) # poor man's multimethod/generic function thingy executors = { @@ -545,13 +545,14 @@ class ResultProxy(object): def convert_result_value(self, arg, engine): raise exceptions.InvalidRequestError("Ambiguous column name '%s' in result set! try 'use_labels' option on select statement." % (self.key)) - def __init__(self, engine, connection, cursor, executioncontext=None, typemap=None): + def __init__(self, engine, connection, cursor, executioncontext=None, typemap=None, columns=None): """ResultProxy objects are constructed via the execute() method on SQLEngine.""" self.connection = connection self.dialect = engine.dialect self.cursor = cursor self.engine = engine self.closed = False + self.columns = columns if executioncontext is not None: self.__executioncontext = executioncontext self.rowcount = executioncontext.get_rowcount(cursor) @@ -611,15 +612,26 @@ class ResultProxy(object): try: rec = self.props[key.key.lower()] except KeyError: -# rec = self.props[key.name.lower()] try: rec = self.props[key.name.lower()] except KeyError: raise exceptions.NoSuchColumnError("Could not locate column in row for column '%s'" % str(key)) elif isinstance(key, str): - rec = self.props[key.lower()] + try: + rec = self.props[key.lower()] + except KeyError: + try: + if self.columns is not None: + rec = self._convert_key(self.columns[key]) + else: + raise + except KeyError: + raise exceptions.NoSuchColumnError("Could not locate column in row for column '%s'" % str(key)) else: - rec = self.props[key] + try: + rec = self.props[key] + except KeyError: + raise exceptions.NoSuchColumnError("Could not locate column in row for column '%s'" % str(key)) self.__key_cache[key] = rec return rec -- 2.47.2