--- /dev/null
+.. change::
+ :tags: datatypes, use case
+ :tickets: 5465
+
+ Implements generic Double, DOUBLE types with compiler mapping to
+ respective DOUBLE/DOUBLE PRECISION/FLOAT types in Dialects.
.. autoclass:: Enum
:members: __init__, create, drop
+.. autoclass:: Double
+ :members:
+
.. autoclass:: Float
:members:
from .types import DATETIME as DATETIME
from .types import DateTime as DateTime
from .types import DECIMAL as DECIMAL
+from .types import DOUBLE
+from .types import Double
from .types import Enum as Enum
from .types import FLOAT as FLOAT
from .types import Float as Float
else:
return "FLOAT(%(precision)s)" % {"precision": precision}
+ def visit_DOUBLE(self, type_, **kw):
+ return "FLOAT"
+
def visit_TINYINT(self, type_, **kw):
return "TINYINT"
_FloatType: _FloatType,
sqltypes.Numeric: NUMERIC,
sqltypes.Float: FLOAT,
+ sqltypes.Double: DOUBLE,
sqltypes.Time: TIME,
sqltypes.Enum: ENUM,
sqltypes.MatchType: _MatchType,
)
-class DOUBLE(_FloatType):
+class DOUBLE(_FloatType, sqltypes.DOUBLE):
"""MySQL DOUBLE type."""
__visit_name__ = "DOUBLE"
return sqltypes.Integer
-class DOUBLE_PRECISION(sqltypes.Float):
+class DOUBLE_PRECISION(sqltypes.Double):
__visit_name__ = "DOUBLE_PRECISION"
def visit_float(self, type_, **kw):
return self.visit_FLOAT(type_, **kw)
+ def visit_double(self, type_, **kw):
+ return self.visit_DOUBLE_PRECISION(type_, **kw)
+
def visit_unicode(self, type_, **kw):
if self.dialect._use_nchar_for_unicode:
return self.visit_NVARCHAR2(type_, **kw)
else:
return self.visit_VARCHAR2(type_, **kw)
+ def visit_DOUBLE(self, type_, **kw):
+ return self.visit_DOUBLE_PRECISION(type_, **kw)
+
def visit_INTERVAL(self, type_, **kw):
return "INTERVAL DAY%s TO SECOND%s" % (
type_.day_precision is not None
__visit_name__ = "BYTEA"
-class DOUBLE_PRECISION(sqltypes.Float):
+class DOUBLE_PRECISION(sqltypes.Double):
__visit_name__ = "DOUBLE_PRECISION"
def visit_DOUBLE_PRECISION(self, type_, **kw):
return "DOUBLE PRECISION"
+ def visit_DOUBLE(self, type_, **kw):
+ return "DOUBLE PRECISION"
+
+ def visit_double(self, type_, **kw):
+ return "DOUBLE PRECISION"
+
def visit_BIGINT(self, type_, **kw):
return "BIGINT"
"DATE_CHAR": sqltypes.DATE,
"DATETIME": sqltypes.DATETIME,
"DATETIME_CHAR": sqltypes.DATETIME,
- "DOUBLE": sqltypes.FLOAT,
+ "DOUBLE": sqltypes.DOUBLE,
"DECIMAL": sqltypes.DECIMAL,
"FLOAT": sqltypes.FLOAT,
"INT": sqltypes.INTEGER,
def visit_FLOAT(self, type_, **kw):
return "FLOAT"
+ def visit_DOUBLE(self, type_, **kw):
+ return "DOUBLE"
+
def visit_REAL(self, type_, **kw):
return "REAL"
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)
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.
+ """
+
+ __visit_name__ = "double"
+
+
class DateTime(_LookupExpressionAdapter, TypeEngine[dt.datetime]):
"""A type for ``datetime.datetime()`` objects.
__visit_name__ = "FLOAT"
+class DOUBLE(Double):
+
+ """The SQL DOUBLE type."""
+
+ __visit_name__ = "DOUBLE"
+
+
class NUMERIC(Numeric):
"""The SQL NUMERIC type."""
"TEXT",
"Text",
"FLOAT",
+ "DOUBLE",
"NUMERIC",
"REAL",
"DECIMAL",
"BigInteger",
"Numeric",
"Float",
+ "Double",
"DateTime",
"Date",
"Time",
from .sql.sqltypes import DATETIME
from .sql.sqltypes import DateTime
from .sql.sqltypes import DECIMAL
+from .sql.sqltypes import DOUBLE
+from .sql.sqltypes import Double
from .sql.sqltypes import Enum
from .sql.sqltypes import FLOAT
from .sql.sqltypes import Float
(types.Float, [], {}, "FLOAT"),
(types.Float, [None], {}, "FLOAT"),
(types.Float, [12], {}, "FLOAT(12)"),
+ (types.Double, [], {}, "FLOAT"),
+ (types.DOUBLE, [], {}, "FLOAT"),
(mssql.MSReal, [], {}, "REAL"),
(types.Integer, [], {}, "INTEGER"),
(types.BigInteger, [], {}, "BIGINT"),
from sqlalchemy import DATETIME
from sqlalchemy import DateTime
from sqlalchemy import DECIMAL
+from sqlalchemy import DOUBLE
+from sqlalchemy import Double
from sqlalchemy import exc
from sqlalchemy import extract
from sqlalchemy import FLOAT
(Float, "t.col"),
(m.MSFloat, "t.col"),
(m.MSDouble, "t.col"),
+ (DOUBLE, "t.col"),
+ (Double, "t.col"),
(m.MSReal, "t.col"),
(m.MSYear, "t.col"),
(m.MSYear(2), "t.col"),
(m.FLOAT, "CAST(t.col AS FLOAT)"),
(Float, "CAST(t.col AS FLOAT)"),
(FLOAT, "CAST(t.col AS FLOAT)"),
+ (Double, "CAST(t.col AS DOUBLE)"),
+ (DOUBLE, "CAST(t.col AS DOUBLE)"),
(m.DOUBLE, "CAST(t.col AS DOUBLE)"),
(m.FLOAT, "CAST(t.col AS FLOAT)"),
argnames="type_,expected",
# coding: utf-8
from sqlalchemy import and_
from sqlalchemy import bindparam
+from sqlalchemy import cast
from sqlalchemy import Computed
from sqlalchemy import exc
from sqlalchemy import except_
from sqlalchemy import text
from sqlalchemy import type_coerce
from sqlalchemy import TypeDecorator
+from sqlalchemy import types as sqltypes
from sqlalchemy import union
from sqlalchemy.dialects.oracle import base as oracle
from sqlalchemy.dialects.oracle import cx_oracle
dialect=dd,
)
+ def test_double_to_oracle_double(self):
+ """test #5465:
+ test sqlalchemy Double/DOUBLE to PostgreSQL DOUBLE PRECISION
+ """
+ d1 = sqltypes.Double
+ d2 = sqltypes.DOUBLE
+
+ self.assert_compile(
+ cast(column("foo"), d1), "CAST(foo AS DOUBLE PRECISION)"
+ )
+ self.assert_compile(
+ cast(column("bar"), d2), "CAST(bar AS DOUBLE PRECISION)"
+ )
+
class SequenceTest(fixtures.TestBase, AssertsCompiledSQL):
def test_basic(self):
# coding: utf-8
+from sqlalchemy import DOUBLE
from sqlalchemy import exc
from sqlalchemy import FLOAT
from sqlalchemy import ForeignKey
connection,
):
specs = [
- (DOUBLE_PRECISION(), FLOAT()),
+ (DOUBLE_PRECISION(), DOUBLE()),
# when binary_precision is supported
# (DOUBLE_PRECISION(), oracle.FLOAT(binary_precision=126)),
(BINARY_DOUBLE(), BINARY_DOUBLE()),
from sqlalchemy import DATE
from sqlalchemy import Date
from sqlalchemy import DateTime
+from sqlalchemy import DOUBLE
+from sqlalchemy import Double
from sqlalchemy import event
from sqlalchemy import FLOAT
from sqlalchemy import Float
Column("numericcol", Numeric(precision=9, scale=2)),
Column("floatcol1", Float()),
Column("floatcol2", FLOAT()),
- Column("doubleprec", oracle.DOUBLE_PRECISION),
+ Column("doubleprec1", oracle.DOUBLE_PRECISION),
+ Column("doubleprec2", Double()),
+ Column("doubleprec3", DOUBLE()),
Column("numbercol1", oracle.NUMBER(9)),
Column("numbercol2", oracle.NUMBER(9, 3)),
Column("numbercol3", oracle.NUMBER),
"CAST(bar AS someschema.somename) AS bar",
)
+ def test_cast_double_pg_double(self):
+ """test #5465:
+
+ test sqlalchemy Double/DOUBLE to PostgreSQL DOUBLE PRECISION
+ """
+ d1 = sqltypes.Double
+ d2 = sqltypes.DOUBLE
+
+ stmt = select(cast(column("foo"), d1), cast(column("bar"), d2))
+ self.assert_compile(
+ stmt,
+ "SELECT CAST(foo AS DOUBLE PRECISION) AS foo, "
+ "CAST(bar AS DOUBLE PRECISION) AS bar",
+ )
+
def test_cast_enum_schema_translate(self):
"""test #6739"""
e1 = Enum("x", "y", "z", name="somename")
from sqlalchemy import Column
from sqlalchemy import column
from sqlalchemy import DateTime
+from sqlalchemy import Double
from sqlalchemy import Enum
from sqlalchemy import exc
from sqlalchemy import Float
Column("x", postgresql.ARRAY(Float)),
Column("y", postgresql.ARRAY(REAL)),
Column("z", postgresql.ARRAY(postgresql.DOUBLE_PRECISION)),
+ Column("w", postgresql.ARRAY(Double)),
Column("q", postgresql.ARRAY(Numeric)),
)
metadata.create_all(connection)
Column("x", sqltypes.ARRAY(Float)),
Column("y", sqltypes.ARRAY(REAL)),
Column("z", sqltypes.ARRAY(postgresql.DOUBLE_PRECISION)),
+ Column("w", sqltypes.ARRAY(Double)),
Column("q", sqltypes.ARRAY(Numeric)),
)
metadata.create_all(connection)
from sqlalchemy import DECIMAL
from sqlalchemy import dialects
from sqlalchemy import distinct
+from sqlalchemy import Double
from sqlalchemy import Enum
from sqlalchemy import exc
from sqlalchemy import FLOAT
eq_(types.Numeric(asdecimal=False).python_type, float)
eq_(types.LargeBinary().python_type, bytes)
eq_(types.Float().python_type, float)
+ eq_(types.Double().python_type, float)
eq_(types.Interval().python_type, datetime.timedelta)
eq_(types.Date().python_type, datetime.date)
eq_(types.DateTime().python_type, datetime.datetime)
dialects.postgresql.FLOAT(), "FLOAT", allow_dialect_select=True
)
+ def test_default_compile_double(self):
+ self.assert_compile(Double(), "DOUBLE")
+
def test_default_compile_mysql_integer(self):
self.assert_compile(
dialects.mysql.INTEGER(display_width=5),