From 56b1f4c8845373b6680d6ab09dcefe36eaeb12fb Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sat, 12 Jan 2013 12:14:15 -0500 Subject: [PATCH] - changelog for pullreq 32 - Fixed a regression whereby the "collation" parameter of the character types CHAR, NCHAR, etc. stopped working, as "collation" is now supported by the base string types. The TEXT, NCHAR, CHAR, VARCHAR types within the MSSQL dialect are now synonyms for the base types. - move out the type rendering tests into DB-agnostic tests and remove some of the old "create" statements. tests here are still very disorganized. --- doc/build/changelog/changelog_08.rst | 19 ++ lib/sqlalchemy/dialects/mssql/base.py | 134 +------- test/dialect/test_mssql.py | 444 ++++++++++++++------------ 3 files changed, 270 insertions(+), 327 deletions(-) diff --git a/doc/build/changelog/changelog_08.rst b/doc/build/changelog/changelog_08.rst index 3f7a488489..154e5fff6c 100644 --- a/doc/build/changelog/changelog_08.rst +++ b/doc/build/changelog/changelog_08.rst @@ -6,6 +6,25 @@ .. changelog:: :version: 0.8.0 + .. change:: + :tags: mssql, bug + + Fixed a regression whereby the "collation" parameter + of the character types CHAR, NCHAR, etc. stopped working, + as "collation" is now supported by the base string types. + The TEXT, NCHAR, CHAR, VARCHAR types within the + MSSQL dialect are now synonyms for the base types. + + .. change:: + :tags: mssql, feature + :tickets: 2644 + :pullreq: 32 + + DDL for IDENTITY columns is now supported on + non-primary key columns, by establishing a + :class:`.Sequence` construct on any + integer column. Courtesy Derek Harland. + .. change:: :tags: examples, bug diff --git a/lib/sqlalchemy/dialects/mssql/base.py b/lib/sqlalchemy/dialects/mssql/base.py index 9cfe3b997f..d7c29654a3 100644 --- a/lib/sqlalchemy/dialects/mssql/base.py +++ b/lib/sqlalchemy/dialects/mssql/base.py @@ -45,13 +45,10 @@ does in other dialects and results in an ``IDENTITY`` column. Collation Support ----------------- -MSSQL specific string types support a collation parameter that -creates a column-level specific collation for the column. The -collation parameter accepts a Windows Collation Name or a SQL -Collation Name. Supported types are MSChar, MSNChar, MSString, -MSNVarchar, MSText, and MSNText. For example:: +Character collations are supported by the base string types, +specified by the string argument "collation":: - from sqlalchemy.dialects.mssql import VARCHAR + from sqlalchemy import VARCHAR Column('login', VARCHAR(32, collation='Latin1_General_CI_AS')) When such a column is associated with a :class:`.Table`, the @@ -59,6 +56,9 @@ CREATE TABLE statement for this column will yield:: login VARCHAR(32) COLLATE Latin1_General_CI_AS NULL +.. versionadded:: 0.8 Character collations are now part of the base string + types. + LIMIT/OFFSET Support -------------------- @@ -176,7 +176,8 @@ from ...engine import reflection, default from ... import types as sqltypes from ...types import INTEGER, BIGINT, SMALLINT, DECIMAL, NUMERIC, \ FLOAT, TIMESTAMP, DATETIME, DATE, BINARY,\ - VARBINARY + VARBINARY, TEXT, VARCHAR, NVARCHAR, CHAR, NCHAR + from ...util import update_wrapper from . import information_schema as ischema @@ -331,132 +332,17 @@ class _StringType(object): """Base for MSSQL string types.""" def __init__(self, collation=None): - self.collation = collation - + super(_StringType, self).__init__(collation=collation) -class TEXT(_StringType, sqltypes.TEXT): - """MSSQL TEXT type, for variable-length text up to 2^31 characters.""" - def __init__(self, length=None, collation=None, **kw): - """Construct a TEXT. - - :param collation: Optional, a column-level collation for this string - value. Accepts a Windows Collation Name or a SQL Collation Name. - - """ - _StringType.__init__(self, collation) - sqltypes.Text.__init__(self, length, **kw) -class NTEXT(_StringType, sqltypes.UnicodeText): +class NTEXT(sqltypes.UnicodeText): """MSSQL NTEXT type, for variable-length unicode text up to 2^30 characters.""" __visit_name__ = 'NTEXT' - def __init__(self, length=None, collation=None, **kw): - """Construct a NTEXT. - - :param collation: Optional, a column-level collation for this string - value. Accepts a Windows Collation Name or a SQL Collation Name. - - """ - _StringType.__init__(self, collation) - sqltypes.UnicodeText.__init__(self, length, **kw) - - -class VARCHAR(_StringType, sqltypes.VARCHAR): - """MSSQL VARCHAR type, for variable-length non-Unicode data with a maximum - of 8,000 characters.""" - - def __init__(self, length=None, collation=None, **kw): - """Construct a VARCHAR. - - :param length: Optinal, maximum data length, in characters. - - :param convert_unicode: defaults to False. If True, convert - ``unicode`` data sent to the database to a ``str`` - bytestring, and convert bytestrings coming back from the - database into ``unicode``. - - Bytestrings are encoded using the dialect's - :attr:`~sqlalchemy.engine.Dialect.encoding`, which - defaults to `utf-8`. - - If False, may be overridden by - :attr:`sqlalchemy.engine.Dialect.convert_unicode`. - - :param collation: Optional, a column-level collation for this string - value. Accepts a Windows Collation Name or a SQL Collation Name. - - """ - _StringType.__init__(self, collation) - sqltypes.VARCHAR.__init__(self, length, **kw) - - -class NVARCHAR(_StringType, sqltypes.NVARCHAR): - """MSSQL NVARCHAR type. - - For variable-length unicode character data up to 4,000 characters.""" - - def __init__(self, length=None, collation=None, **kw): - """Construct a NVARCHAR. - - :param length: Optional, Maximum data length, in characters. - - :param collation: Optional, a column-level collation for this string - value. Accepts a Windows Collation Name or a SQL Collation Name. - - """ - _StringType.__init__(self, collation) - sqltypes.NVARCHAR.__init__(self, length, **kw) - - -class CHAR(_StringType, sqltypes.CHAR): - """MSSQL CHAR type, for fixed-length non-Unicode data with a maximum - of 8,000 characters.""" - - def __init__(self, length=None, collation=None, **kw): - """Construct a CHAR. - - :param length: Optinal, maximum data length, in characters. - - :param convert_unicode: defaults to False. If True, convert - ``unicode`` data sent to the database to a ``str`` - bytestring, and convert bytestrings coming back from the - database into ``unicode``. - - Bytestrings are encoded using the dialect's - :attr:`~sqlalchemy.engine.Dialect.encoding`, which - defaults to `utf-8`. - - If False, may be overridden by - :attr:`sqlalchemy.engine.Dialect.convert_unicode`. - - :param collation: Optional, a column-level collation for this string - value. Accepts a Windows Collation Name or a SQL Collation Name. - - """ - _StringType.__init__(self, collation) - sqltypes.CHAR.__init__(self, length, **kw) - - -class NCHAR(_StringType, sqltypes.NCHAR): - """MSSQL NCHAR type. - - For fixed-length unicode character data up to 4,000 characters.""" - - def __init__(self, length=None, collation=None, **kw): - """Construct an NCHAR. - - :param length: Optional, Maximum data length, in characters. - - :param collation: Optional, a column-level collation for this string - value. Accepts a Windows Collation Name or a SQL Collation Name. - - """ - _StringType.__init__(self, collation) - sqltypes.NCHAR.__init__(self, length, **kw) class IMAGE(sqltypes.LargeBinary): diff --git a/test/dialect/test_mssql.py b/test/dialect/test_mssql.py index f1c4b4df42..972602378d 100644 --- a/test/dialect/test_mssql.py +++ b/test/dialect/test_mssql.py @@ -1,9 +1,7 @@ # -*- encoding: utf-8 -from sqlalchemy.testing import eq_ +from sqlalchemy.testing import eq_, engines, pickleable import datetime import os -import re -import warnings from sqlalchemy import * from sqlalchemy import types, exc, schema, event from sqlalchemy.orm import * @@ -33,7 +31,7 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL): self.assert_compile(t.select().with_hint(t, 'WITH (NOLOCK)'), 'SELECT sometable.somecolumn FROM sometable WITH (NOLOCK)') - def test_join_with_hint (self): + def test_join_with_hint(self): t1 = table('t1', column('a', Integer), column('b', String), @@ -640,8 +638,9 @@ class IdentityInsertTest(fixtures.TestBase, AssertsCompiledSQL): class ReflectionTest(fixtures.TestBase, ComparesTables): __only_on__ = 'mssql' + @testing.provide_metadata def test_basic_reflection(self): - meta = MetaData(testing.db) + meta = self.metadata users = Table( 'engine_users', @@ -662,7 +661,6 @@ class ReflectionTest(fixtures.TestBase, ComparesTables): server_default='5'), Column('test9', types.BINARY(100)), Column('test_numeric', types.Numeric()), - test_needs_fk=True, ) addresses = Table( @@ -672,21 +670,17 @@ class ReflectionTest(fixtures.TestBase, ComparesTables): Column('remote_user_id', types.Integer, ForeignKey(users.c.user_id)), Column('email_address', types.String(20)), - test_needs_fk=True, ) meta.create_all() - try: - meta2 = MetaData() - reflected_users = Table('engine_users', meta2, - autoload=True, - autoload_with=testing.db) - reflected_addresses = Table('engine_email_addresses', - meta2, autoload=True, autoload_with=testing.db) - self.assert_tables_equal(users, reflected_users) - self.assert_tables_equal(addresses, reflected_addresses) - finally: - meta.drop_all() + meta2 = MetaData() + reflected_users = Table('engine_users', meta2, + autoload=True, + autoload_with=testing.db) + reflected_addresses = Table('engine_email_addresses', + meta2, autoload=True, autoload_with=testing.db) + self.assert_tables_equal(users, reflected_users) + self.assert_tables_equal(addresses, reflected_addresses) @testing.provide_metadata def test_identity(self): @@ -1315,7 +1309,232 @@ class TimeTypeTest(fixtures.TestBase): result_processor = mssql_time_type.result_processor(None, None) eq_(expected, result_processor(value)) -class TypesTest(fixtures.TestBase, AssertsExecutionResults, ComparesTables): + +class TypeDDLTest(fixtures.TestBase): + def test_boolean(self): + "Exercise type specification for boolean type." + + columns = [ + # column type, args, kwargs, expected ddl + (Boolean, [], {}, + 'BIT'), + ] + + metadata = MetaData() + table_args = ['test_mssql_boolean', metadata] + for index, spec in enumerate(columns): + type_, args, kw, res = spec + table_args.append( + Column('c%s' % index, type_(*args, **kw), nullable=None)) + + boolean_table = Table(*table_args) + dialect = mssql.dialect() + gen = dialect.ddl_compiler(dialect, schema.CreateTable(boolean_table)) + + for col in boolean_table.c: + index = int(col.name[1:]) + testing.eq_(gen.get_column_specification(col), + "%s %s" % (col.name, columns[index][3])) + self.assert_(repr(col)) + + + def test_numeric(self): + "Exercise type specification and options for numeric types." + + columns = [ + # column type, args, kwargs, expected ddl + (types.NUMERIC, [], {}, + 'NUMERIC'), + (types.NUMERIC, [None], {}, + 'NUMERIC'), + (types.NUMERIC, [12, 4], {}, + 'NUMERIC(12, 4)'), + + (types.Float, [], {}, + 'FLOAT'), + (types.Float, [None], {}, + 'FLOAT'), + (types.Float, [12], {}, + 'FLOAT(12)'), + (mssql.MSReal, [], {}, + 'REAL'), + + (types.Integer, [], {}, + 'INTEGER'), + (types.BigInteger, [], {}, + 'BIGINT'), + (mssql.MSTinyInteger, [], {}, + 'TINYINT'), + (types.SmallInteger, [], {}, + 'SMALLINT'), + ] + + metadata = MetaData() + table_args = ['test_mssql_numeric', metadata] + for index, spec in enumerate(columns): + type_, args, kw, res = spec + table_args.append( + Column('c%s' % index, type_(*args, **kw), nullable=None)) + + numeric_table = Table(*table_args) + dialect = mssql.dialect() + gen = dialect.ddl_compiler(dialect, schema.CreateTable(numeric_table)) + + for col in numeric_table.c: + index = int(col.name[1:]) + testing.eq_(gen.get_column_specification(col), + "%s %s" % (col.name, columns[index][3])) + self.assert_(repr(col)) + + + def test_char(self): + """Exercise COLLATE-ish options on string types.""" + + columns = [ + (mssql.MSChar, [], {}, + 'CHAR'), + (mssql.MSChar, [1], {}, + 'CHAR(1)'), + (mssql.MSChar, [1], {'collation': 'Latin1_General_CI_AS'}, + 'CHAR(1) COLLATE Latin1_General_CI_AS'), + + (mssql.MSNChar, [], {}, + 'NCHAR'), + (mssql.MSNChar, [1], {}, + 'NCHAR(1)'), + (mssql.MSNChar, [1], {'collation': 'Latin1_General_CI_AS'}, + 'NCHAR(1) COLLATE Latin1_General_CI_AS'), + + (mssql.MSString, [], {}, + 'VARCHAR(max)'), + (mssql.MSString, [1], {}, + 'VARCHAR(1)'), + (mssql.MSString, [1], {'collation': 'Latin1_General_CI_AS'}, + 'VARCHAR(1) COLLATE Latin1_General_CI_AS'), + + (mssql.MSNVarchar, [], {}, + 'NVARCHAR(max)'), + (mssql.MSNVarchar, [1], {}, + 'NVARCHAR(1)'), + (mssql.MSNVarchar, [1], {'collation': 'Latin1_General_CI_AS'}, + 'NVARCHAR(1) COLLATE Latin1_General_CI_AS'), + + (mssql.MSText, [], {}, + 'TEXT'), + (mssql.MSText, [], {'collation': 'Latin1_General_CI_AS'}, + 'TEXT COLLATE Latin1_General_CI_AS'), + + (mssql.MSNText, [], {}, + 'NTEXT'), + (mssql.MSNText, [], {'collation': 'Latin1_General_CI_AS'}, + 'NTEXT COLLATE Latin1_General_CI_AS'), + ] + + metadata = MetaData() + table_args = ['test_mssql_charset', metadata] + for index, spec in enumerate(columns): + type_, args, kw, res = spec + table_args.append( + Column('c%s' % index, type_(*args, **kw), nullable=None)) + + charset_table = Table(*table_args) + dialect = mssql.dialect() + gen = dialect.ddl_compiler(dialect, schema.CreateTable(charset_table)) + + for col in charset_table.c: + index = int(col.name[1:]) + testing.eq_(gen.get_column_specification(col), + "%s %s" % (col.name, columns[index][3])) + self.assert_(repr(col)) + + + def test_timestamp(self): + """Exercise TIMESTAMP column.""" + + dialect = mssql.dialect() + + metadata = MetaData() + spec, expected = (TIMESTAMP, 'TIMESTAMP') + t = Table('mssql_ts', metadata, + Column('id', Integer, primary_key=True), + Column('t', spec, nullable=None)) + gen = dialect.ddl_compiler(dialect, schema.CreateTable(t)) + testing.eq_(gen.get_column_specification(t.c.t), "t %s" % expected) + self.assert_(repr(t.c.t)) + + def test_money(self): + """Exercise type specification for money types.""" + + columns = [(mssql.MSMoney, [], {}, 'MONEY'), + (mssql.MSSmallMoney, [], {}, 'SMALLMONEY')] + metadata = MetaData() + table_args = ['test_mssql_money', metadata] + for index, spec in enumerate(columns): + type_, args, kw, res = spec + table_args.append(Column('c%s' % index, type_(*args, **kw), + nullable=None)) + money_table = Table(*table_args) + dialect = mssql.dialect() + gen = dialect.ddl_compiler(dialect, + schema.CreateTable(money_table)) + for col in money_table.c: + index = int(col.name[1:]) + testing.eq_(gen.get_column_specification(col), '%s %s' + % (col.name, columns[index][3])) + self.assert_(repr(col)) + + def test_binary(self): + "Exercise type specification for binary types." + + columns = [ + # column type, args, kwargs, expected ddl + (mssql.MSBinary, [], {}, + 'BINARY'), + (mssql.MSBinary, [10], {}, + 'BINARY(10)'), + + (types.BINARY, [], {}, + 'BINARY'), + (types.BINARY, [10], {}, + 'BINARY(10)'), + + (mssql.MSVarBinary, [], {}, + 'VARBINARY(max)'), + (mssql.MSVarBinary, [10], {}, + 'VARBINARY(10)'), + + (types.VARBINARY, [10], {}, + 'VARBINARY(10)'), + (types.VARBINARY, [], {}, + 'VARBINARY(max)'), + + (mssql.MSImage, [], {}, + 'IMAGE'), + + (mssql.IMAGE, [], {}, + 'IMAGE'), + + (types.LargeBinary, [], {}, + 'IMAGE'), + ] + + metadata = MetaData() + table_args = ['test_mssql_binary', metadata] + for index, spec in enumerate(columns): + type_, args, kw, res = spec + table_args.append(Column('c%s' % index, type_(*args, **kw), + nullable=None)) + binary_table = Table(*table_args) + dialect = mssql.dialect() + gen = dialect.ddl_compiler(dialect, + schema.CreateTable(binary_table)) + for col in binary_table.c: + index = int(col.name[1:]) + testing.eq_(gen.get_column_specification(col), '%s %s' + % (col.name, columns[index][3])) + self.assert_(repr(col)) + +class TypeRoundTripTest(fixtures.TestBase, AssertsExecutionResults, ComparesTables): __only_on__ = 'mssql' @classmethod @@ -1429,31 +1648,6 @@ class TypesTest(fixtures.TestBase, AssertsExecutionResults, ComparesTables): except Exception, e: raise e - def test_money(self): - """Exercise type specification for money types.""" - - columns = [(mssql.MSMoney, [], {}, 'MONEY'), - (mssql.MSSmallMoney, [], {}, 'SMALLMONEY')] - table_args = ['test_mssql_money', metadata] - for index, spec in enumerate(columns): - type_, args, kw, res = spec - table_args.append(Column('c%s' % index, type_(*args, **kw), - nullable=None)) - money_table = Table(*table_args) - dialect = mssql.dialect() - gen = dialect.ddl_compiler(dialect, - schema.CreateTable(money_table)) - for col in money_table.c: - index = int(col.name[1:]) - testing.eq_(gen.get_column_specification(col), '%s %s' - % (col.name, columns[index][3])) - self.assert_(repr(col)) - try: - money_table.create(checkfirst=True) - assert True - except: - raise - money_table.drop() # todo this should suppress warnings, but it does not @emits_warning_on('mssql+mxodbc', r'.*does not have any indexes.*') @@ -1555,7 +1749,8 @@ class TypesTest(fixtures.TestBase, AssertsExecutionResults, ComparesTables): == d1).execute().fetchall(), [(d1, t1, d2)]) @emits_warning_on('mssql+mxodbc', r'.*does not have any indexes.*') - def test_binary(self): + @testing.provide_metadata + def test_binary_reflection(self): "Exercise type specification for binary types." columns = [ @@ -1590,20 +1785,13 @@ class TypesTest(fixtures.TestBase, AssertsExecutionResults, ComparesTables): 'IMAGE'), ] + metadata = self.metadata table_args = ['test_mssql_binary', metadata] for index, spec in enumerate(columns): type_, args, kw, res = spec table_args.append(Column('c%s' % index, type_(*args, **kw), nullable=None)) binary_table = Table(*table_args) - dialect = mssql.dialect() - gen = dialect.ddl_compiler(dialect, - schema.CreateTable(binary_table)) - for col in binary_table.c: - index = int(col.name[1:]) - testing.eq_(gen.get_column_specification(col), '%s %s' - % (col.name, columns[index][3])) - self.assert_(repr(col)) metadata.create_all() reflected_binary = Table('test_mssql_binary', MetaData(testing.db), autoload=True) @@ -1618,156 +1806,6 @@ class TypesTest(fixtures.TestBase, AssertsExecutionResults, ComparesTables): testing.eq_(col.type.length, binary_table.c[col.name].type.length) - def test_boolean(self): - "Exercise type specification for boolean type." - - columns = [ - # column type, args, kwargs, expected ddl - (Boolean, [], {}, - 'BIT'), - ] - - table_args = ['test_mssql_boolean', metadata] - for index, spec in enumerate(columns): - type_, args, kw, res = spec - table_args.append( - Column('c%s' % index, type_(*args, **kw), nullable=None)) - - boolean_table = Table(*table_args) - dialect = mssql.dialect() - gen = dialect.ddl_compiler(dialect, schema.CreateTable(boolean_table)) - - for col in boolean_table.c: - index = int(col.name[1:]) - testing.eq_(gen.get_column_specification(col), - "%s %s" % (col.name, columns[index][3])) - self.assert_(repr(col)) - - metadata.create_all() - - def test_numeric(self): - "Exercise type specification and options for numeric types." - - columns = [ - # column type, args, kwargs, expected ddl - (types.NUMERIC, [], {}, - 'NUMERIC'), - (types.NUMERIC, [None], {}, - 'NUMERIC'), - (types.NUMERIC, [12, 4], {}, - 'NUMERIC(12, 4)'), - - (types.Float, [], {}, - 'FLOAT'), - (types.Float, [None], {}, - 'FLOAT'), - (types.Float, [12], {}, - 'FLOAT(12)'), - (mssql.MSReal, [], {}, - 'REAL'), - - (types.Integer, [], {}, - 'INTEGER'), - (types.BigInteger, [], {}, - 'BIGINT'), - (mssql.MSTinyInteger, [], {}, - 'TINYINT'), - (types.SmallInteger, [], {}, - 'SMALLINT'), - ] - - table_args = ['test_mssql_numeric', metadata] - for index, spec in enumerate(columns): - type_, args, kw, res = spec - table_args.append( - Column('c%s' % index, type_(*args, **kw), nullable=None)) - - numeric_table = Table(*table_args) - dialect = mssql.dialect() - gen = dialect.ddl_compiler(dialect, schema.CreateTable(numeric_table)) - - for col in numeric_table.c: - index = int(col.name[1:]) - testing.eq_(gen.get_column_specification(col), - "%s %s" % (col.name, columns[index][3])) - self.assert_(repr(col)) - - metadata.create_all() - - def test_char(self): - """Exercise COLLATE-ish options on string types.""" - - columns = [ - (mssql.MSChar, [], {}, - 'CHAR'), - (mssql.MSChar, [1], {}, - 'CHAR(1)'), - (mssql.MSChar, [1], {'collation': 'Latin1_General_CI_AS'}, - 'CHAR(1) COLLATE Latin1_General_CI_AS'), - - (mssql.MSNChar, [], {}, - 'NCHAR'), - (mssql.MSNChar, [1], {}, - 'NCHAR(1)'), - (mssql.MSNChar, [1], {'collation': 'Latin1_General_CI_AS'}, - 'NCHAR(1) COLLATE Latin1_General_CI_AS'), - - (mssql.MSString, [], {}, - 'VARCHAR(max)'), - (mssql.MSString, [1], {}, - 'VARCHAR(1)'), - (mssql.MSString, [1], {'collation': 'Latin1_General_CI_AS'}, - 'VARCHAR(1) COLLATE Latin1_General_CI_AS'), - - (mssql.MSNVarchar, [], {}, - 'NVARCHAR(max)'), - (mssql.MSNVarchar, [1], {}, - 'NVARCHAR(1)'), - (mssql.MSNVarchar, [1], {'collation': 'Latin1_General_CI_AS'}, - 'NVARCHAR(1) COLLATE Latin1_General_CI_AS'), - - (mssql.MSText, [], {}, - 'TEXT'), - (mssql.MSText, [], {'collation': 'Latin1_General_CI_AS'}, - 'TEXT COLLATE Latin1_General_CI_AS'), - - (mssql.MSNText, [], {}, - 'NTEXT'), - (mssql.MSNText, [], {'collation': 'Latin1_General_CI_AS'}, - 'NTEXT COLLATE Latin1_General_CI_AS'), - ] - - table_args = ['test_mssql_charset', metadata] - for index, spec in enumerate(columns): - type_, args, kw, res = spec - table_args.append( - Column('c%s' % index, type_(*args, **kw), nullable=None)) - - charset_table = Table(*table_args) - dialect = mssql.dialect() - gen = dialect.ddl_compiler(dialect, schema.CreateTable(charset_table)) - - for col in charset_table.c: - index = int(col.name[1:]) - testing.eq_(gen.get_column_specification(col), - "%s %s" % (col.name, columns[index][3])) - self.assert_(repr(col)) - - metadata.create_all() - - def test_timestamp(self): - """Exercise TIMESTAMP column.""" - - dialect = mssql.dialect() - - spec, expected = (TIMESTAMP,'TIMESTAMP') - t = Table('mssql_ts', metadata, - Column('id', Integer, primary_key=True), - Column('t', spec, nullable=None)) - gen = dialect.ddl_compiler(dialect, schema.CreateTable(t)) - testing.eq_(gen.get_column_specification(t.c.t), "t %s" % expected) - self.assert_(repr(t.c.t)) - t.create(checkfirst=True) def test_autoincrement(self): Table('ai_1', metadata, -- 2.47.2