summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/engine/default.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2020-07-19 17:39:14 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2020-07-19 17:45:41 -0400
commit83b3ce6b7c7991d2faf314dc44571de9e6e9c27b (patch)
tree35e789e551aae9f15a2dd40a9ab66f38f0ba3cfb /lib/sqlalchemy/engine/default.py
parent547e959157f841f4f6d1e405ceed14755fcbd0bd (diff)
downloadsqlalchemy-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.py104
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)