From: Mike Bayer Date: Tue, 5 Apr 2011 16:40:55 +0000 (-0400) Subject: - REAL has been added to the core types. Supported X-Git-Tag: rel_0_7b4~37 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b462373b461f652ab20085a612ebd777836ac4da;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - 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] --- diff --git a/CHANGES b/CHANGES index dc7dba7ada..c92ddcf08a 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 74a04a8c09..04b9b37b54 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 0cab28da1e..a20554dc0d 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 bec0562a95..ca2678e58c 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 16d9217853..7ff017d834 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 21e0312f5a..33dc8a73e4 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 cc2f461f98..7fdd74628f 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 9d39bd8251..d939d51cd8 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 36357597cc..43d8d708ba 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 76303c10c6..7c409e0e63 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 b52f7644c1..e8d0b6f22f 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 bbf4765604..1f8a87bc09 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 d154aada7c..7865a5296d 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):