summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES7
-rw-r--r--doc/build/core/types.rst3
-rw-r--r--lib/sqlalchemy/__init__.py1
-rw-r--r--lib/sqlalchemy/dialects/drizzle/base.py2
-rw-r--r--lib/sqlalchemy/dialects/mssql/base.py10
-rw-r--r--lib/sqlalchemy/dialects/mysql/base.py2
-rw-r--r--lib/sqlalchemy/dialects/postgresql/base.py8
-rw-r--r--lib/sqlalchemy/dialects/sqlite/__init__.py4
-rw-r--r--lib/sqlalchemy/dialects/sqlite/base.py5
-rw-r--r--lib/sqlalchemy/sql/compiler.py6
-rw-r--r--lib/sqlalchemy/types.py9
-rw-r--r--test/dialect/test_postgresql.py2
-rw-r--r--test/sql/test_types.py9
13 files changed, 43 insertions, 25 deletions
diff --git a/CHANGES b/CHANGES
index dc7dba7ad..c92ddcf08 100644
--- a/CHANGES
+++ b/CHANGES
@@ -57,6 +57,13 @@ CHANGES
these elements are only applied when the Table
is newly created. [ticket:2109]
+- types
+ - REAL has been added to the core types. Supported
+ by Postgresql, SQL Server, MySQL, SQLite. Note
+ that the SQL Server and MySQL versions, which
+ add extra arguments, are also still available
+ from those dialects. [ticket:2081]
+
-event
- Added @event.listens_for() decorator, given
target + event name, applies the decorated
diff --git a/doc/build/core/types.rst b/doc/build/core/types.rst
index 74a04a8c0..04b9b37b5 100644
--- a/doc/build/core/types.rst
+++ b/doc/build/core/types.rst
@@ -163,6 +163,9 @@ on all databases.
.. autoclass:: NUMERIC
:show-inheritance:
+.. autoclass:: REAL
+ :show-inheritance:
+
.. autoclass:: SMALLINT
:show-inheritance:
diff --git a/lib/sqlalchemy/__init__.py b/lib/sqlalchemy/__init__.py
index 0cab28da1..a20554dc0 100644
--- a/lib/sqlalchemy/__init__.py
+++ b/lib/sqlalchemy/__init__.py
@@ -75,6 +75,7 @@ from sqlalchemy.types import (
NUMERIC,
Numeric,
PickleType,
+ REAL,
SMALLINT,
SmallInteger,
String,
diff --git a/lib/sqlalchemy/dialects/drizzle/base.py b/lib/sqlalchemy/dialects/drizzle/base.py
index bec0562a9..ca2678e58 100644
--- a/lib/sqlalchemy/dialects/drizzle/base.py
+++ b/lib/sqlalchemy/dialects/drizzle/base.py
@@ -218,7 +218,7 @@ class DOUBLE(_FloatType):
super(DOUBLE, self).__init__(precision=precision, scale=scale,
asdecimal=asdecimal, **kw)
-class REAL(_FloatType):
+class REAL(_FloatType, sqltypes.REAL):
"""Drizzle REAL type."""
__visit_name__ = 'REAL'
diff --git a/lib/sqlalchemy/dialects/mssql/base.py b/lib/sqlalchemy/dialects/mssql/base.py
index 16d921785..7ff017d83 100644
--- a/lib/sqlalchemy/dialects/mssql/base.py
+++ b/lib/sqlalchemy/dialects/mssql/base.py
@@ -217,13 +217,12 @@ RESERVED_WORDS = set(
])
-class REAL(sqltypes.Float):
- """A type for ``real`` numbers."""
-
+class REAL(sqltypes.REAL):
__visit_name__ = 'REAL'
def __init__(self, **kw):
- kw.setdefault('precision', 24)
+ # REAL is a synonym for FLOAT(24) on SQL server
+ kw['precision'] = 24
super(REAL, self).__init__(**kw)
class TINYINT(sqltypes.Integer):
@@ -548,9 +547,6 @@ class MSTypeCompiler(compiler.GenericTypeCompiler):
else:
return "FLOAT(%(precision)s)" % {'precision': precision}
- def visit_REAL(self, type_):
- return "REAL"
-
def visit_TINYINT(self, type_):
return "TINYINT"
diff --git a/lib/sqlalchemy/dialects/mysql/base.py b/lib/sqlalchemy/dialects/mysql/base.py
index 21e0312f5..33dc8a73e 100644
--- a/lib/sqlalchemy/dialects/mysql/base.py
+++ b/lib/sqlalchemy/dialects/mysql/base.py
@@ -354,7 +354,7 @@ class DOUBLE(_FloatType):
super(DOUBLE, self).__init__(precision=precision, scale=scale,
asdecimal=asdecimal, **kw)
-class REAL(_FloatType):
+class REAL(_FloatType, sqltypes.REAL):
"""MySQL REAL type."""
__visit_name__ = 'REAL'
diff --git a/lib/sqlalchemy/dialects/postgresql/base.py b/lib/sqlalchemy/dialects/postgresql/base.py
index cc2f461f9..7fdd74628 100644
--- a/lib/sqlalchemy/dialects/postgresql/base.py
+++ b/lib/sqlalchemy/dialects/postgresql/base.py
@@ -99,7 +99,7 @@ except ImportError:
from sqlalchemy.types import INTEGER, BIGINT, SMALLINT, VARCHAR, \
CHAR, TEXT, FLOAT, NUMERIC, \
- DATE, BOOLEAN
+ DATE, BOOLEAN, REAL
RESERVED_WORDS = set(
["all", "analyse", "analyze", "and", "any", "array", "as", "asc",
@@ -123,9 +123,6 @@ _DECIMAL_TYPES = (1231, 1700)
_FLOAT_TYPES = (700, 701, 1021, 1022)
_INT_TYPES = (20, 21, 23, 26, 1005, 1007, 1016)
-class REAL(sqltypes.Float):
- __visit_name__ = "REAL"
-
class BYTEA(sqltypes.LargeBinary):
__visit_name__ = 'BYTEA'
@@ -669,9 +666,6 @@ class PGTypeCompiler(compiler.GenericTypeCompiler):
def visit_BYTEA(self, type_):
return "BYTEA"
- def visit_REAL(self, type_):
- return "REAL"
-
def visit_ARRAY(self, type_):
return self.process(type_.item_type) + '[]'
diff --git a/lib/sqlalchemy/dialects/sqlite/__init__.py b/lib/sqlalchemy/dialects/sqlite/__init__.py
index 9d39bd825..d939d51cd 100644
--- a/lib/sqlalchemy/dialects/sqlite/__init__.py
+++ b/lib/sqlalchemy/dialects/sqlite/__init__.py
@@ -11,10 +11,10 @@ base.dialect = pysqlite.dialect
from sqlalchemy.dialects.sqlite.base import \
- BLOB, BOOLEAN, CHAR, DATE, DATETIME, DECIMAL, FLOAT, INTEGER,\
+ BLOB, BOOLEAN, CHAR, DATE, DATETIME, DECIMAL, FLOAT, INTEGER, REAL,\
NUMERIC, SMALLINT, TEXT, TIME, TIMESTAMP, VARCHAR, dialect
__all__ = (
'BLOB', 'BOOLEAN', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'FLOAT', 'INTEGER',
- 'NUMERIC', 'SMALLINT', 'TEXT', 'TIME', 'TIMESTAMP', 'VARCHAR', 'dialect'
+ 'NUMERIC', 'SMALLINT', 'TEXT', 'TIME', 'TIMESTAMP', 'VARCHAR', 'dialect', 'REAL'
) \ No newline at end of file
diff --git a/lib/sqlalchemy/dialects/sqlite/base.py b/lib/sqlalchemy/dialects/sqlite/base.py
index 36357597c..43d8d708b 100644
--- a/lib/sqlalchemy/dialects/sqlite/base.py
+++ b/lib/sqlalchemy/dialects/sqlite/base.py
@@ -63,8 +63,7 @@ from sqlalchemy.sql import compiler
from sqlalchemy import processors
from sqlalchemy.types import BLOB, BOOLEAN, CHAR, DATE, DATETIME, DECIMAL,\
- FLOAT, INTEGER, NUMERIC, SMALLINT, TEXT, TIME,\
- TIMESTAMP, VARCHAR
+ FLOAT, REAL, INTEGER, NUMERIC, SMALLINT, TEXT, TIME, TIMESTAMP, VARCHAR
class _DateTimeMixin(object):
_reg = None
@@ -272,7 +271,7 @@ ischema_names = {
'INT': sqltypes.INTEGER,
'INTEGER': sqltypes.INTEGER,
'NUMERIC': sqltypes.NUMERIC,
- 'REAL': sqltypes.Numeric,
+ 'REAL': sqltypes.REAL,
'SMALLINT': sqltypes.SMALLINT,
'TEXT': sqltypes.TEXT,
'TIME': sqltypes.TIME,
diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py
index 76303c10c..7c409e0e6 100644
--- a/lib/sqlalchemy/sql/compiler.py
+++ b/lib/sqlalchemy/sql/compiler.py
@@ -1479,6 +1479,9 @@ class GenericTypeCompiler(engine.TypeCompiler):
def visit_FLOAT(self, type_):
return "FLOAT"
+ def visit_REAL(self, type_):
+ return "REAL"
+
def visit_NUMERIC(self, type_):
if type_.precision is None:
return "NUMERIC"
@@ -1565,6 +1568,9 @@ class GenericTypeCompiler(engine.TypeCompiler):
def visit_integer(self, type_):
return self.visit_INTEGER(type_)
+ def visit_real(self, type_):
+ return self.visit_REAL(type_)
+
def visit_float(self, type_):
return self.visit_FLOAT(type_)
diff --git a/lib/sqlalchemy/types.py b/lib/sqlalchemy/types.py
index b52f7644c..e8d0b6f22 100644
--- a/lib/sqlalchemy/types.py
+++ b/lib/sqlalchemy/types.py
@@ -13,8 +13,8 @@ For more information see the SQLAlchemy documentation on types.
"""
__all__ = [ 'TypeEngine', 'TypeDecorator', 'AbstractType', 'UserDefinedType',
'INT', 'CHAR', 'VARCHAR', 'NCHAR', 'NVARCHAR','TEXT', 'Text',
- 'FLOAT', 'NUMERIC', 'DECIMAL', 'TIMESTAMP', 'DATETIME', 'CLOB',
- 'BLOB', 'BOOLEAN', 'SMALLINT', 'INTEGER', 'DATE', 'TIME',
+ 'FLOAT', 'NUMERIC', 'REAL', 'DECIMAL', 'TIMESTAMP', 'DATETIME',
+ 'CLOB', 'BLOB', 'BOOLEAN', 'SMALLINT', 'INTEGER', 'DATE', 'TIME',
'String', 'Integer', 'SmallInteger', 'BigInteger', 'Numeric',
'Float', 'DateTime', 'Date', 'Time', 'LargeBinary', 'Binary',
'Boolean', 'Unicode', 'MutableType', 'Concatenable',
@@ -1995,6 +1995,11 @@ class Interval(_DateAffinity, TypeDecorator):
return self.impl._coerce_compared_value(op, value)
+class REAL(Float):
+ """The SQL REAL type."""
+
+ __visit_name__ = 'REAL'
+
class FLOAT(Float):
"""The SQL FLOAT type."""
diff --git a/test/dialect/test_postgresql.py b/test/dialect/test_postgresql.py
index bbf476560..1f8a87bc0 100644
--- a/test/dialect/test_postgresql.py
+++ b/test/dialect/test_postgresql.py
@@ -287,7 +287,7 @@ class FloatCoercionTest(fixtures.TablesTest, AssertsExecutionResults):
metadata = self.metadata
t1 = Table('t', metadata,
Column('x', postgresql.ARRAY(Float)),
- Column('y', postgresql.ARRAY(postgresql.REAL)),
+ Column('y', postgresql.ARRAY(REAL)),
Column('z', postgresql.ARRAY(postgresql.DOUBLE_PRECISION)),
Column('q', postgresql.ARRAY(Numeric))
)
diff --git a/test/sql/test_types.py b/test/sql/test_types.py
index d154aada7..7865a5296 100644
--- a/test/sql/test_types.py
+++ b/test/sql/test_types.py
@@ -55,6 +55,7 @@ class AdaptTest(fixtures.TestBase):
for dialect in self._all_dialects():
for type_, expected in (
+ (REAL, "REAL"),
(FLOAT, "FLOAT"),
(NUMERIC, "NUMERIC"),
(DECIMAL, "DECIMAL"),
@@ -120,7 +121,13 @@ class AdaptTest(fixtures.TestBase):
for k in t1.__dict__:
if k == 'impl':
continue
- eq_(getattr(t2, k), t1.__dict__[k])
+ # assert each value was copied, or that
+ # the adapted type has a more specific
+ # value than the original (i.e. SQL Server
+ # applies precision=24 for REAL)
+ assert \
+ getattr(t2, k) == t1.__dict__[k] or \
+ t1.__dict__[k] is None
def test_plain_init_deprecation_warning(self):
for typ in (Integer, Date, SmallInteger):