From: Mike Bayer Date: Thu, 26 Jul 2007 22:09:52 +0000 (+0000) Subject: - very rudimental support for OUT parameters added; use sql.outparam(name, type) X-Git-Tag: rel_0_4_6~9 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f9faba23b20617a672c0e3c21bcc207f1953d9b0;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - very rudimental support for OUT parameters added; use sql.outparam(name, type) to set up an OUT parameter, just like bindparam(); after execution, values are avaiable via result.out_parameters dictionary. [ticket:507] - dialect.get_type_map() apparently never worked, not sure why unit test seemed to work the first time around. - OracleText doesn't seem to return cx_oracle.LOB. --- diff --git a/CHANGES b/CHANGES index 01c245038b..ec8d8fcce1 100644 --- a/CHANGES +++ b/CHANGES @@ -217,6 +217,10 @@ from SelectResults isn't present anymore, need to use join(). - postgres - Added PGArray datatype for using postgres array datatypes +- oracle + - very rudimental support for OUT parameters added; use sql.outparam(name, type) + to set up an OUT parameter, just like bindparam(); after execution, values are + avaiable via result.out_parameters dictionary. [ticket:507] 0.3.11 - orm diff --git a/lib/sqlalchemy/databases/oracle.py b/lib/sqlalchemy/databases/oracle.py index 38a7b50de8..cdf14c9fa7 100644 --- a/lib/sqlalchemy/databases/oracle.py +++ b/lib/sqlalchemy/databases/oracle.py @@ -85,11 +85,11 @@ class OracleText(sqltypes.TEXT): def get_col_spec(self): return "CLOB" - def convert_result_value(self, value, dialect): - if value is None: - return None - else: - return super(OracleText, self).convert_result_value(value.read(), dialect) + # def convert_result_value(self, value, dialect): + # if value is None: + # return None + # else: + # return super(OracleText, self).convert_result_value(value.read(), dialect) class OracleRaw(sqltypes.Binary): @@ -178,8 +178,26 @@ class OracleExecutionContext(default.DefaultExecutionContext): super(OracleExecutionContext, self).pre_exec() if self.dialect.auto_setinputsizes: self.set_input_sizes() + if self.compiled_parameters is not None and not isinstance(self.compiled_parameters, list): + for key in self.compiled_parameters: + (bindparam, name, value) = self.compiled_parameters.get_parameter(key) + if bindparam.isoutparam: + dbtype = bindparam.type.dialect_impl(self.dialect).get_dbapi_type(self.dialect.dbapi) + if not hasattr(self, 'out_parameters'): + self.out_parameters = {} + self.out_parameters[name] = self.cursor.var(dbtype) + self.parameters[name] = self.out_parameters[name] def get_result_proxy(self): + if hasattr(self, 'out_parameters'): + if self.compiled_parameters is not None: + for k in self.out_parameters: + type = self.compiled_parameters.get_type(k) + self.out_parameters[k] = type.dialect_impl(self.dialect).convert_result_value(self.out_parameters[k].getvalue(), self.dialect) + else: + for k in self.out_parameters: + self.out_parameters[k] = self.out_parameters[k].getvalue() + if self.cursor.description is not None: for column in self.cursor.description: type_code = column[1] diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py index ad02942556..5a2de33895 100644 --- a/lib/sqlalchemy/engine/base.py +++ b/lib/sqlalchemy/engine/base.py @@ -1102,6 +1102,7 @@ class ResultProxy(object): return self.context.get_rowcount() rowcount = property(_get_rowcount) lastrowid = property(lambda s:s.cursor.lastrowid) + out_parameters = property(lambda s:s.context.out_parameters) def _init_metadata(self): if hasattr(self, '_ResultProxy__props'): diff --git a/lib/sqlalchemy/engine/default.py b/lib/sqlalchemy/engine/default.py index a87a2e0170..03af9272ac 100644 --- a/lib/sqlalchemy/engine/default.py +++ b/lib/sqlalchemy/engine/default.py @@ -33,8 +33,9 @@ class DefaultDialect(base.Dialect): dialect_module = sys.modules[self.__class__.__module__] map = {} for obj in dialect_module.__dict__.values(): - if isinstance(obj, types.TypeEngine): - map[obj().get_dbapi_type(self.dialect)] = obj + if isinstance(obj, type) and issubclass(obj, types.TypeEngine): + obj = obj() + map[obj.get_dbapi_type(self.dbapi)] = obj self._dbapi_type_map = map def decode_result_columnname(self, name): diff --git a/lib/sqlalchemy/sql.py b/lib/sqlalchemy/sql.py index a40af7d6d0..01588e92da 100644 --- a/lib/sqlalchemy/sql.py +++ b/lib/sqlalchemy/sql.py @@ -35,7 +35,7 @@ __all__ = ['Alias', 'ClauseElement', 'ClauseParameters', 'between', 'bindparam', 'case', 'cast', 'column', 'delete', 'desc', 'distinct', 'except_', 'except_all', 'exists', 'extract', 'func', 'modifier', 'insert', 'intersect', 'intersect_all', 'join', 'literal', - 'literal_column', 'not_', 'null', 'or_', 'outerjoin', 'select', + 'literal_column', 'not_', 'null', 'or_', 'outparam', 'outerjoin', 'select', 'subquery', 'table', 'text', 'union', 'union_all', 'update',] BIND_PARAMS = re.compile(r'(?