diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2020-07-19 17:39:14 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2020-07-19 17:45:41 -0400 |
| commit | 83b3ce6b7c7991d2faf314dc44571de9e6e9c27b (patch) | |
| tree | 35e789e551aae9f15a2dd40a9ab66f38f0ba3cfb /lib/sqlalchemy/engine/default.py | |
| parent | 547e959157f841f4f6d1e405ceed14755fcbd0bd (diff) | |
| download | sqlalchemy-83b3ce6b7c7991d2faf314dc44571de9e6e9c27b.tar.gz | |
Revise setinputsizes approach
in order to support asyncpg as well as pg8000,
we need to revise setinputsizes to work for more cases as well
as adjust NativeForEmulated a bit to work more completely with
the INTERVAL datatype.
- put most of the setinputsizes work into the compiler where
the computation can be cached.
- support per-element setinputsizes for a tuple
- adjust TypeDecorator so that _unwrapped_dialect_impl
will honor a type that the dialect links to directly in
it's adaption mapping. Decouble _unwrapped_dialect_impl
from TypeDecorator._gen_dialect_impl() which has a different
purpose. This allows setinputsizes to do the right thing
with the INTERVAL datatype.
- test cases for Oracle with Variant continue to work
Change-Id: I9e1ea33aeca3b92b365daa4a356d778191070c03
Diffstat (limited to 'lib/sqlalchemy/engine/default.py')
| -rw-r--r-- | lib/sqlalchemy/engine/default.py | 104 |
1 files changed, 60 insertions, 44 deletions
diff --git a/lib/sqlalchemy/engine/default.py b/lib/sqlalchemy/engine/default.py index e567e11e7..c431fa755 100644 --- a/lib/sqlalchemy/engine/default.py +++ b/lib/sqlalchemy/engine/default.py @@ -1406,37 +1406,19 @@ class DefaultExecutionContext(interfaces.ExecutionContext): currently cx_oracle. """ + if self.isddl: + return None - if not hasattr(self.compiled, "bind_names"): + inputsizes = self.compiled._get_set_input_sizes_lookup( + translate=translate, + include_types=include_types, + exclude_types=exclude_types, + ) + if inputsizes is None: return - inputsizes = {} - for bindparam in self.compiled.bind_names: - if bindparam in self.compiled.literal_execute_params: - continue - - dialect_impl = bindparam.type._unwrapped_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 - ) - ): - inputsizes[bindparam] = dbtype - else: - inputsizes[bindparam] = None - if self.dialect._has_events: + inputsizes = dict(inputsizes) self.dialect.dispatch.do_setinputsizes( inputsizes, self.cursor, self.statement, self.parameters, self ) @@ -1445,14 +1427,29 @@ class DefaultExecutionContext(interfaces.ExecutionContext): positional_inputsizes = [] for key in self.compiled.positiontup: bindparam = self.compiled.binds[key] - dbtype = inputsizes.get(bindparam, None) - if dbtype is not None: - if key in self._expanded_parameters: + if bindparam in self.compiled.literal_execute_params: + continue + + if key in self._expanded_parameters: + if bindparam._expanding_in_types: + num = len(bindparam._expanding_in_types) + dbtypes = inputsizes[bindparam] positional_inputsizes.extend( - [dbtype] * len(self._expanded_parameters[key]) + [ + dbtypes[idx % num] + for idx, key in enumerate( + self._expanded_parameters[key] + ) + ] ) else: - positional_inputsizes.append(dbtype) + dbtype = inputsizes.get(bindparam, None) + positional_inputsizes.extend( + dbtype for dbtype in self._expanded_parameters[key] + ) + else: + dbtype = inputsizes[bindparam] + positional_inputsizes.append(dbtype) try: self.cursor.setinputsizes(*positional_inputsizes) except BaseException as e: @@ -1462,21 +1459,40 @@ class DefaultExecutionContext(interfaces.ExecutionContext): else: keyword_inputsizes = {} for bindparam, key in self.compiled.bind_names.items(): - dbtype = inputsizes.get(bindparam, None) - if dbtype is not None: - if translate: - # TODO: this part won't work w/ the - # expanded_parameters feature, e.g. for cx_oracle - # quoted bound names - key = translate.get(key, key) - if not self.dialect.supports_unicode_binds: - key = self.dialect._encoder(key)[0] - if key in self._expanded_parameters: + if bindparam in self.compiled.literal_execute_params: + continue + + if key in self._expanded_parameters: + if bindparam._expanding_in_types: + num = len(bindparam._expanding_in_types) + dbtypes = inputsizes[bindparam] keyword_inputsizes.update( - (expand_key, dbtype) - for expand_key in self._expanded_parameters[key] + [ + (key, dbtypes[idx % num]) + for idx, key in enumerate( + self._expanded_parameters[key] + ) + ] ) else: + dbtype = inputsizes.get(bindparam, None) + if dbtype is not None: + keyword_inputsizes.update( + (expand_key, dbtype) + for expand_key in self._expanded_parameters[ + key + ] + ) + else: + dbtype = inputsizes.get(bindparam, None) + if dbtype is not None: + if translate: + # TODO: this part won't work w/ the + # expanded_parameters feature, e.g. for cx_oracle + # quoted bound names + key = translate.get(key, key) + if not self.dialect.supports_unicode_binds: + key = self.dialect._encoder(key)[0] keyword_inputsizes[key] = dbtype try: self.cursor.setinputsizes(**keyword_inputsizes) |
