summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql/elements.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2020-12-18 12:22:12 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2020-12-18 21:50:14 -0500
commit27766512b2d037a8f0048dccc6e2f02c281fbc9a (patch)
treef6f721ee5c1b4da3e0c644b43ab4c8bcec4debfa /lib/sqlalchemy/sql/elements.py
parent8294a336b1e6f23b5a7244e7aa457321fd3580bd (diff)
downloadsqlalchemy-27766512b2d037a8f0048dccc6e2f02c281fbc9a.tar.gz
Improve type detection for Values / Tuple
Fixed issue in new :class:`_sql.Values` construct where passing tuples of objects would fall back to per-value type detection rather than making use of the :class:`_schema.Column` objects passed directly to :class:`_sql.Values` that tells SQLAlchemy what the expected type is. This would lead to issues for objects such as enumerations and numpy strings that are not actually necessary since the expected type is given. note this changes NullType() to raise CompileError for literal_processor; NullType() does not imply the actual value NULL as much as it does "unknown type" so this should make failure modes more clear. Fixes: #5785 Change-Id: Ifbf5e78373102380b301098f30e15011efa98b5e
Diffstat (limited to 'lib/sqlalchemy/sql/elements.py')
-rw-r--r--lib/sqlalchemy/sql/elements.py25
1 files changed, 21 insertions, 4 deletions
diff --git a/lib/sqlalchemy/sql/elements.py b/lib/sqlalchemy/sql/elements.py
index ab8701dd6..75c1fc1bf 100644
--- a/lib/sqlalchemy/sql/elements.py
+++ b/lib/sqlalchemy/sql/elements.py
@@ -2497,11 +2497,28 @@ class Tuple(ClauseList, ColumnElement):
"""
sqltypes = util.preloaded.sql_sqltypes
- clauses = [
- coercions.expect(roles.ExpressionElementRole, c) for c in clauses
- ]
- self.type = sqltypes.TupleType(*[arg.type for arg in clauses])
+ types = kw.pop("types", None)
+ if types is None:
+ clauses = [
+ coercions.expect(roles.ExpressionElementRole, c)
+ for c in clauses
+ ]
+ else:
+ if len(types) != len(clauses):
+ raise exc.ArgumentError(
+ "Wrong number of elements for %d-tuple: %r "
+ % (len(types), clauses)
+ )
+ clauses = [
+ coercions.expect(
+ roles.ExpressionElementRole,
+ c,
+ type_=typ if not typ._isnull else None,
+ )
+ for typ, c in zip(types, clauses)
+ ]
+ self.type = sqltypes.TupleType(*[arg.type for arg in clauses])
super(Tuple, self).__init__(*clauses, **kw)
@property