summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql
diff options
context:
space:
mode:
authorzeeeeeb <5767468+zeeeeeb@users.noreply.github.com>2022-02-12 14:00:02 -0500
committermike bayer <mike_mp@zzzcomputing.com>2022-02-25 00:51:32 +0000
commitb9d231869d7e39decabdec12478e359c4dcb95ee (patch)
treec6d8ebecc9c73206816cb54211f28a6dd7180e76 /lib/sqlalchemy/sql
parent0353a9db76db6a46fa63d99a1d05c5cac45ea460 (diff)
downloadsqlalchemy-b9d231869d7e39decabdec12478e359c4dcb95ee.tar.gz
Implement generic Double and related fixed types
Added :class:`.Double`, :class:`.DOUBLE`, :class:`.DOUBLE_PRECISION` datatypes to the base ``sqlalchemy.`` module namespace, for explicit use of double/double precision as well as generic "double" datatypes. Use :class:`.Double` for generic support that will resolve to DOUBLE/DOUBLE PRECISION/FLOAT as needed for different backends. Implemented DDL and reflection support for ``FLOAT`` datatypes which include an explicit "binary_precision" value. Using the Oracle-specific :class:`_oracle.FLOAT` datatype, the new parameter :paramref:`_oracle.FLOAT.binary_precision` may be specified which will render Oracle's precision for floating point types directly. This value is interpreted during reflection. Upon reflecting back a ``FLOAT`` datatype, the datatype returned is one of :class:`_types.DOUBLE_PRECISION` for a ``FLOAT`` for a precision of 126 (this is also Oracle's default precision for ``FLOAT``), :class:`_types.REAL` for a precision of 63, and :class:`_oracle.FLOAT` for a custom precision, as per Oracle documentation. As part of this change, the generic :paramref:`_sqltypes.Float.precision` value is explicitly rejected when generating DDL for Oracle, as this precision cannot be accurately converted to "binary precision"; instead, an error message encourages the use of :meth:`_sqltypes.TypeEngine.with_variant` so that Oracle's specific form of precision may be chosen exactly. This is a backwards-incompatible change in behavior, as the previous "precision" value was silently ignored for Oracle. Fixes: #5465 Closes: #7674 Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/7674 Pull-request-sha: 5c68419e5aee2e27bf21a8ac9eb5950d196c77e5 Change-Id: I831f4af3ee3b23fde02e8f6393c83e23dd7cd34d
Diffstat (limited to 'lib/sqlalchemy/sql')
-rw-r--r--lib/sqlalchemy/sql/compiler.py9
-rw-r--r--lib/sqlalchemy/sql/sqltypes.py125
2 files changed, 125 insertions, 9 deletions
diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py
index b140f9297..131281a16 100644
--- a/lib/sqlalchemy/sql/compiler.py
+++ b/lib/sqlalchemy/sql/compiler.py
@@ -4888,6 +4888,12 @@ class GenericTypeCompiler(TypeCompiler):
def visit_FLOAT(self, type_, **kw):
return "FLOAT"
+ def visit_DOUBLE(self, type_, **kw):
+ return "DOUBLE"
+
+ def visit_DOUBLE_PRECISION(self, type_, **kw):
+ return "DOUBLE PRECISION"
+
def visit_REAL(self, type_, **kw):
return "REAL"
@@ -5006,6 +5012,9 @@ class GenericTypeCompiler(TypeCompiler):
def visit_float(self, type_, **kw):
return self.visit_FLOAT(type_, **kw)
+ def visit_double(self, type_, **kw):
+ return self.visit_DOUBLE(type_, **kw)
+
def visit_numeric(self, type_, **kw):
return self.visit_NUMERIC(type_, **kw)
diff --git a/lib/sqlalchemy/sql/sqltypes.py b/lib/sqlalchemy/sql/sqltypes.py
index 819f1dc9a..d022a24ca 100644
--- a/lib/sqlalchemy/sql/sqltypes.py
+++ b/lib/sqlalchemy/sql/sqltypes.py
@@ -578,7 +578,30 @@ class Float(Numeric):
Construct a Float.
:param precision: the numeric precision for use in DDL ``CREATE
- TABLE``.
+ TABLE``. Backends **should** attempt to ensure this precision
+ indicates a number of digits for the generic
+ :class:`_sqltypes.Float` datatype.
+
+ .. note:: For the Oracle backend, the
+ :paramref:`_sqltypes.Float.precision` parameter is not accepted
+ when rendering DDL, as Oracle does not support float precision
+ specified as a number of decimal places. Instead, use the
+ Oracle-specific :class:`_oracle.FLOAT` datatype and specify the
+ :paramref:`_oracle.FLOAT.binary_precision` parameter. This is new
+ in version 2.0 of SQLAlchemy.
+
+ To create a database agnostic :class:`_types.Float` that
+ separately specifies binary precision for Oracle, use
+ :meth:`_types.TypeEngine.with_variant` as follows::
+
+ from sqlalchemy import Column
+ from sqlalchemy import Float
+ from sqlalchemy.dialects import oracle
+
+ Column(
+ "float_data",
+ Float(5).with_variant(oracle.FLOAT(binary_precision=16), "oracle")
+ )
:param asdecimal: the same flag as that of :class:`.Numeric`, but
defaults to ``False``. Note that setting this flag to ``True``
@@ -595,7 +618,7 @@ class Float(Numeric):
.. versionadded:: 0.9.0
- """
+ """ # noqa: E501
self.precision = precision
self.asdecimal = asdecimal
self.decimal_return_scale = decimal_return_scale
@@ -611,6 +634,20 @@ class Float(Numeric):
return None
+class Double(Float):
+ """A type for double ``FLOAT`` floating point types.
+
+ Typically generates a ``DOUBLE`` or ``DOUBLE_PRECISION`` in DDL,
+ and otherwise acts like a normal :class:`.Float` on the Python
+ side.
+
+ .. versionadded:: 2.0
+
+ """
+
+ __visit_name__ = "double"
+
+
class DateTime(_LookupExpressionAdapter, TypeEngine[dt.datetime]):
"""A type for ``datetime.datetime()`` objects.
@@ -2769,35 +2806,93 @@ class TupleType(TypeEngine[Tuple[Any]]):
class REAL(Float):
- """The SQL REAL type."""
+ """The SQL REAL type.
+
+ .. seealso::
+
+ :class:`_types.Float` - documentation for the base type.
+
+ """
__visit_name__ = "REAL"
class FLOAT(Float):
- """The SQL FLOAT type."""
+ """The SQL FLOAT type.
+
+ .. seealso::
+
+ :class:`_types.Float` - documentation for the base type.
+
+ """
__visit_name__ = "FLOAT"
+class DOUBLE(Double):
+ """The SQL DOUBLE type.
+
+ .. versionadded:: 2.0
+
+ .. seealso::
+
+ :class:`_types.Double` - documentation for the base type.
+
+ """
+
+ __visit_name__ = "DOUBLE"
+
+
+class DOUBLE_PRECISION(Double):
+ """The SQL DOUBLE PRECISION type.
+
+ .. versionadded:: 2.0
+
+ .. seealso::
+
+ :class:`_types.Double` - documentation for the base type.
+
+ """
+
+ __visit_name__ = "DOUBLE_PRECISION"
+
+
class NUMERIC(Numeric):
- """The SQL NUMERIC type."""
+ """The SQL NUMERIC type.
+
+ .. seealso::
+
+ :class:`_types.Numeric` - documentation for the base type.
+
+ """
__visit_name__ = "NUMERIC"
class DECIMAL(Numeric):
- """The SQL DECIMAL type."""
+ """The SQL DECIMAL type.
+
+ .. seealso::
+
+ :class:`_types.Numeric` - documentation for the base type.
+
+ """
__visit_name__ = "DECIMAL"
class INTEGER(Integer):
- """The SQL INT or INTEGER type."""
+ """The SQL INT or INTEGER type.
+
+ .. seealso::
+
+ :class:`_types.Integer` - documentation for the base type.
+
+ """
__visit_name__ = "INTEGER"
@@ -2807,14 +2902,26 @@ INT = INTEGER
class SMALLINT(SmallInteger):
- """The SQL SMALLINT type."""
+ """The SQL SMALLINT type.
+
+ .. seealso::
+
+ :class:`_types.SmallInteger` - documentation for the base type.
+
+ """
__visit_name__ = "SMALLINT"
class BIGINT(BigInteger):
- """The SQL BIGINT type."""
+ """The SQL BIGINT type.
+
+ .. seealso::
+
+ :class:`_types.BigInteger` - documentation for the base type.
+
+ """
__visit_name__ = "BIGINT"