From: Michael Trier Date: Fri, 12 Dec 2008 04:49:24 +0000 (+0000) Subject: Support for three levels of column nullability: NULL, NOT NULL, and the database... X-Git-Tag: rel_0_5_0~105 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f9b8641269b17a5f29ed58df46286f881d82035f;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Support for three levels of column nullability: NULL, NOT NULL, and the database's configured default. The default Column configuration (nullable=True) will now generate NULL in the DDL. Previously no specification was emitted and the database default would take effect (usually NULL, but not always). To explicitly request the database default, configure columns with nullable=None and no specification will be emitted in DDL. Fixes #1243. --- diff --git a/CHANGES b/CHANGES index 007766a7af..3f97dc797d 100644 --- a/CHANGES +++ b/CHANGES @@ -169,6 +169,15 @@ CHANGES - Added experimental support of savepoints. It currently does not work fully with sessions. + - Support for three levels of column nullability: NULL, NOT NULL, + and the database's configured default. The default Column + configuration (nullable=True) will now generate NULL in the DDL. + Previously no specification was emitted and the database default + would take effect (usually NULL, but not always). To explicitly + request the database default, configure columns with + nullable=None and no specification will be emitted in DDL. This + is backwards incompatible behavior. [ticket:1243] + - postgres - Calling alias.execute() in conjunction with server_side_cursors won't raise AttributeError. diff --git a/lib/sqlalchemy/databases/mssql.py b/lib/sqlalchemy/databases/mssql.py index c4a773426f..5fb4361b99 100644 --- a/lib/sqlalchemy/databases/mssql.py +++ b/lib/sqlalchemy/databases/mssql.py @@ -14,7 +14,7 @@ CREATE TABLE test ( id INTEGER NOT NULL IDENTITY(100,10) PRIMARY KEY, - name VARCHAR(20) + name VARCHAR(20) NULL, ) Note that the start & increment values for sequences are optional @@ -29,6 +29,19 @@ * Experimental implemention of LIMIT / OFFSET with row_number() +* Support for three levels of column nullability provided. The default + nullability allows nulls:: + + name VARCHAR(20) NULL + + If ``nullable=None`` is specified then no specification is made. In other + words the database's configured default is used. This will render:: + + name VARCHAR(20) + + If ``nullable`` is True or False then the column will be ``NULL` or + ``NOT NULL`` respectively. + Known issues / TODO: * No support for more than one ``IDENTITY`` column per table @@ -1069,8 +1082,11 @@ class MSSQLSchemaGenerator(compiler.SchemaGenerator): if column.default is None or (isinstance(column.default, schema.Sequence) and column.default.optional): column.sequence = schema.Sequence(column.name + '_seq') - if not column.nullable: - colspec += " NOT NULL" + if column.nullable is not None: + if not column.nullable: + colspec += " NOT NULL" + else: + colspec += " NULL" if hasattr(column, 'sequence'): column.table.has_sequence = column diff --git a/test/dialect/mssql.py b/test/dialect/mssql.py index 5a4b38f6e9..5d97cf1484 100755 --- a/test/dialect/mssql.py +++ b/test/dialect/mssql.py @@ -247,6 +247,48 @@ class GenerativeQueryTest(TestBase): assert list(query[:10]) == orig[:10] assert list(query[:10]) == orig[:10] + +class SchemaTest(TestBase): + + def setUp(self): + self.column = Column('test_column', Integer) + + def test_that_mssql_default_nullability_emits_null(self): + schemagenerator = \ + mssql.MSSQLDialect().schemagenerator(mssql.MSSQLDialect(), None) + column_specification = \ + schemagenerator.get_column_specification(self.column) + assert "test_column INTEGER NULL" == column_specification, \ + column_specification + + def test_that_mssql_none_nullability_does_not_emit_nullability(self): + schemagenerator = \ + mssql.MSSQLDialect().schemagenerator(mssql.MSSQLDialect(), None) + self.column.nullable = None + column_specification = \ + schemagenerator.get_column_specification(self.column) + assert "test_column INTEGER" == column_specification, \ + column_specification + + def test_that_mssql_specified_nullable_emits_null(self): + schemagenerator = \ + mssql.MSSQLDialect().schemagenerator(mssql.MSSQLDialect(), None) + self.column.nullable = True + column_specification = \ + schemagenerator.get_column_specification(self.column) + assert "test_column INTEGER NULL" == column_specification, \ + column_specification + + def test_that_mssql_specified_not_nullable_emits_not_null(self): + schemagenerator = \ + mssql.MSSQLDialect().schemagenerator(mssql.MSSQLDialect(), None) + self.column.nullable = False + column_specification = \ + schemagenerator.get_column_specification(self.column) + assert "test_column INTEGER NOT NULL" == column_specification, \ + column_specification + + def full_text_search_missing(): """Test if full text search is not implemented and return False if it is and True otherwise."""