From: Mike Bayer Date: Wed, 9 Nov 2016 13:42:12 +0000 (-0500) Subject: Compare to metadata_impl in compare_type() to guard against custom TypeDecorator X-Git-Tag: rel_0_8_9~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=01e9b8df995ae5ae404c3973ab0b1a99e9c08dce;p=thirdparty%2Fsqlalchemy%2Falembic.git Compare to metadata_impl in compare_type() to guard against custom TypeDecorator Fixed bug where usage of a custom TypeDecorator which returns a per-dialect type via :meth:`.TypeDecorator.load_dialect_impl` that differs significantly from the default "impl" for the type decorator would fail to compare correctly during autogenerate. Change-Id: I384df35be9513bf8a2ae55e7daa9a52c23108a49 Fixes: #395 --- diff --git a/alembic/ddl/impl.py b/alembic/ddl/impl.py index 56b4d59c..52cc4702 100644 --- a/alembic/ddl/impl.py +++ b/alembic/ddl/impl.py @@ -256,7 +256,7 @@ class DefaultImpl(with_metaclass(ImplMeta)): ): comparator = _type_comparators.get(conn_type._type_affinity, None) - return comparator and comparator(metadata_type, conn_type) + return comparator and comparator(metadata_impl, conn_type) else: return True diff --git a/docs/build/changelog.rst b/docs/build/changelog.rst index 6c1d7d24..f8a89be2 100644 --- a/docs/build/changelog.rst +++ b/docs/build/changelog.rst @@ -6,6 +6,15 @@ Changelog .. changelog:: :version: 0.8.9 + .. change:: + :tags: bug, autogenerate + :tickets: 395 + + Fixed bug where usage of a custom TypeDecorator which returns a + per-dialect type via :meth:`.TypeDecorator.load_dialect_impl` that differs + significantly from the default "impl" for the type decorator would fail + to compare correctly during autogenerate. + .. change:: :tags: bug, autogenerate, postgresql :tickets: 392 diff --git a/tests/test_autogen_diffs.py b/tests/test_autogen_diffs.py index 04c9e967..4816134f 100644 --- a/tests/test_autogen_diffs.py +++ b/tests/test_autogen_diffs.py @@ -5,7 +5,8 @@ from sqlalchemy import MetaData, Column, Table, Integer, String, Text, \ TypeDecorator, CheckConstraint, text, PrimaryKeyConstraint, \ ForeignKeyConstraint, VARCHAR, DECIMAL, DateTime, BigInteger, BIGINT, \ SmallInteger -from sqlalchemy.types import NULLTYPE +from sqlalchemy.dialects import sqlite +from sqlalchemy.types import NULLTYPE, VARBINARY from sqlalchemy.engine.reflection import Inspector from alembic.operations import ops @@ -592,6 +593,26 @@ class CompareTypeSpecificityTest(TestBase): return impl.DefaultImpl( default.DefaultDialect(), None, False, True, None, {}) + def test_typedec_to_nonstandard(self): + + class PasswordType(TypeDecorator): + impl = VARBINARY + + def copy(self, **kw): + return PasswordType(self.impl.length) + + def load_dialect_impl(self, dialect): + if dialect.name == 'default': + impl = sqlite.NUMERIC(self.length) + else: + impl = VARBINARY(self.length) + return dialect.type_descriptor(impl) + + impl = self._fixture() + impl.compare_type( + Column('x', sqlite.NUMERIC(50)), + Column('x', PasswordType(50))) + def test_string(self): t1 = String(30) t2 = String(40)