From 9488480abea15298ded6996aa13b42edf134e467 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Wed, 9 Oct 2019 13:55:19 -0400 Subject: pass executemany context to _repr_params Fixed bug where parameter repr as used in logging and error reporting needs additional context in order to distinguish between a list of parameters for a single statement and a list of parameter lists, as the "list of lists" structure could also indicate a single parameter list where the first parameter itself is a list, such as for an array parameter. The engine/connection now passes in an additional boolean indicating how the parameters should be considered. The only SQLAlchemy backend that expects arrays as parameters is that of psycopg2 which uses pyformat parameters, so this issue has not been too apparent, however as other drivers that use positional gain more features it is important that this be supported. It also eliminates the need for the parameter repr function to guess based on the parameter structure passed. Fixes: #4902 Change-Id: I086246ee0eb51484adbefd83e07295fa56576c5f --- lib/sqlalchemy/sql/util.py | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'lib/sqlalchemy/sql') diff --git a/lib/sqlalchemy/sql/util.py b/lib/sqlalchemy/sql/util.py index 5aeed0c1c..e109852a2 100644 --- a/lib/sqlalchemy/sql/util.py +++ b/lib/sqlalchemy/sql/util.py @@ -464,31 +464,29 @@ class _repr_params(_repr_base): """ - __slots__ = "params", "batches" + __slots__ = "params", "batches", "ismulti" - def __init__(self, params, batches, max_chars=300): + def __init__(self, params, batches, max_chars=300, ismulti=None): self.params = params + self.ismulti = ismulti self.batches = batches self.max_chars = max_chars def __repr__(self): + if self.ismulti is None: + return self.trunc(self.params) + if isinstance(self.params, list): typ = self._LIST - ismulti = self.params and isinstance( - self.params[0], (list, dict, tuple) - ) + elif isinstance(self.params, tuple): typ = self._TUPLE - ismulti = self.params and isinstance( - self.params[0], (list, dict, tuple) - ) elif isinstance(self.params, dict): typ = self._DICT - ismulti = False else: return self.trunc(self.params) - if ismulti and len(self.params) > self.batches: + if self.ismulti and len(self.params) > self.batches: msg = " ... displaying %i of %i total bound parameter sets ... " return " ".join( ( @@ -499,7 +497,7 @@ class _repr_params(_repr_base): self._repr_multi(self.params[-2:], typ)[1:], ) ) - elif ismulti: + elif self.ismulti: return self._repr_multi(self.params, typ) else: return self._repr_params(self.params, typ) -- cgit v1.2.1