diff options
-rw-r--r-- | CHANGES | 7 | ||||
-rw-r--r-- | doc/build/core/types.rst | 3 | ||||
-rw-r--r-- | lib/sqlalchemy/__init__.py | 1 | ||||
-rw-r--r-- | lib/sqlalchemy/dialects/drizzle/base.py | 2 | ||||
-rw-r--r-- | lib/sqlalchemy/dialects/mssql/base.py | 10 | ||||
-rw-r--r-- | lib/sqlalchemy/dialects/mysql/base.py | 2 | ||||
-rw-r--r-- | lib/sqlalchemy/dialects/postgresql/base.py | 8 | ||||
-rw-r--r-- | lib/sqlalchemy/dialects/sqlite/__init__.py | 4 | ||||
-rw-r--r-- | lib/sqlalchemy/dialects/sqlite/base.py | 5 | ||||
-rw-r--r-- | lib/sqlalchemy/sql/compiler.py | 6 | ||||
-rw-r--r-- | lib/sqlalchemy/types.py | 9 | ||||
-rw-r--r-- | test/dialect/test_postgresql.py | 2 | ||||
-rw-r--r-- | test/sql/test_types.py | 9 |
13 files changed, 43 insertions, 25 deletions
@@ -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): |