--- /dev/null
+.. change::
+ :tags: bug, mssql, reflection
+ :tickets: 13451
+
+ Fixed issue in SQL Server reflection where ``TEXT`` and ``NTEXT`` columns
+ would be reflected with a spurious length of 16 and 8, respectively. These
+ are unlengthed LOB datatypes; the value originates from the
+ ``sys.columns.max_length`` column, which reports the size of the in-row LOB
+ pointer rather than a character length for these types. The reflected
+ :class:`_mssql.TEXT` and :class:`_mssql.NTEXT` types now have a ``length``
+ of ``None``, so that a reflected table emits valid DDL when re-created,
+ which previously failed with "Cannot specify a column width on data type
+ text".
elif coltype in (
MSString,
MSChar,
- MSText,
):
kwargs["length"] = maxlen if maxlen != -1 else None
if collation:
elif coltype in (
MSNVarchar,
MSNChar,
- MSNText,
):
kwargs["length"] = maxlen // 2 if maxlen != -1 else None
if collation:
kwargs["collation"] = collation
+ elif coltype in (
+ MSText,
+ MSNText,
+ ):
+ # TEXT / NTEXT are unlengthed LOB types.
+ # sys.columns.max_length reports 16 for these, which is the
+ # size of the in-row LOB pointer and not a character length,
+ # so no length is applied.
+ if collation:
+ kwargs["collation"] = collation
if coltype is None:
if base_type is not None and base_type != type_:
"CREATE TABLE type_test (col1 %s NULL)" % ddl,
)
+ def test_lob_types_no_length(self, metadata, connection):
+ """TEXT / NTEXT / IMAGE are unlengthed, and a reflected version of
+ such a table must remain creatable.
+
+ issue #13451
+
+ """
+ Table(
+ "lob_type_test",
+ metadata,
+ Column("id", types.Integer, primary_key=True),
+ Column("t", mssql.TEXT),
+ Column("nt", mssql.NTEXT),
+ Column("img", mssql.IMAGE),
+ )
+ metadata.create_all(connection)
+
+ m2 = MetaData()
+ table2 = Table("lob_type_test", m2, autoload_with=connection)
+ eq_(
+ {c.name: c.type.length for c in table2.c if c.name != "id"},
+ {"t": None, "nt": None, "img": None},
+ )
+
+ # the reflected types round trip back into valid DDL; a length
+ # here would be rejected with "Cannot specify a column width on
+ # data type text"
+ Table(
+ "lob_type_test_2", metadata, *[c._copy() for c in table2.c]
+ ).create(connection)
+
def test_identity(self, metadata, connection):
table = Table(
"identity_test",