From c7ae04d1c5c4aa6c6099584ae386d6ab9ef7b290 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Fri, 18 May 2018 12:51:40 -0400 Subject: call setinputsizes() for integer types Altered the Oracle dialect such that when an :class:`.Integer` type is in use, the cx_Oracle.NUMERIC type is set up for setinputsizes(). In SQLAlchemy 1.1 and earlier, cx_Oracle.NUMERIC was passed for all numeric types unconditionally, and in 1.2 this was removed to allow for better numeric precision. However, for integers, some database/client setups will fail to coerce boolean values True/False into integers which introduces regressive behavior when using SQLAlchemy 1.2. Overall, the setinputsizes logic seems like it will need a lot more flexibility going forward so this is a start for that. Change-Id: Ida80cc2c2c37ffc0e05da4b5df2dadfab55a01f2 Fixes: #4259 --- lib/sqlalchemy/engine/default.py | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) (limited to 'lib/sqlalchemy/engine') diff --git a/lib/sqlalchemy/engine/default.py b/lib/sqlalchemy/engine/default.py index 099e694b6..ea806deae 100644 --- a/lib/sqlalchemy/engine/default.py +++ b/lib/sqlalchemy/engine/default.py @@ -1126,19 +1126,26 @@ class DefaultExecutionContext(interfaces.ExecutionContext): if not hasattr(self.compiled, 'bind_names'): return - types = dict( - (self.compiled.bind_names[bindparam], bindparam.type) - for bindparam in self.compiled.bind_names) + key_to_dbapi_type = {} + for bindparam in self.compiled.bind_names: + key = self.compiled.bind_names[bindparam] + dialect_impl = bindparam.type.dialect_impl(self.dialect) + dialect_impl_cls = type(dialect_impl) + dbtype = dialect_impl.get_dbapi_type(self.dialect.dbapi) + if dbtype is not None and ( + not exclude_types or dbtype not in exclude_types and + dialect_impl_cls not in exclude_types + ) and ( + not include_types or dbtype in include_types or + dialect_impl_cls in include_types + ): + key_to_dbapi_type[key] = dbtype if self.dialect.positional: inputsizes = [] for key in self.compiled.positiontup: - typeengine = types[key] - dbtype = typeengine.dialect_impl(self.dialect).\ - get_dbapi_type(self.dialect.dbapi) - if dbtype is not None and \ - (not exclude_types or dbtype not in exclude_types) and \ - (not include_types or dbtype in include_types): + if key in key_to_dbapi_type: + dbtype = key_to_dbapi_type[key] if key in self._expanded_parameters: inputsizes.extend( [dbtype] * len(self._expanded_parameters[key])) @@ -1152,12 +1159,8 @@ class DefaultExecutionContext(interfaces.ExecutionContext): else: inputsizes = {} for key in self.compiled.bind_names.values(): - typeengine = types[key] - dbtype = typeengine.dialect_impl(self.dialect).\ - get_dbapi_type(self.dialect.dbapi) - if dbtype is not None and \ - (not exclude_types or dbtype not in exclude_types) and \ - (not include_types or dbtype in include_types): + if key in key_to_dbapi_type: + dbtype = key_to_dbapi_type[key] if translate: # TODO: this part won't work w/ the # expanded_parameters feature, e.g. for cx_oracle -- cgit v1.2.1