From 54c5abb15caeb14ddfc70d54424a59dbf8ef3132 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Fri, 2 Jun 2017 10:20:27 -0400 Subject: [PATCH] Adjust for Variant returning itself as impl Fixed bug where autogen comparison of a :class:`.Variant` datatype would not compare to the dialect level type for the "default" implementation of the :class:`.Variant`, returning the type as changed between database and table metadata. Change-Id: Ie94779ece9f1c768375cdbdc4124c98f9c11bb86 Fixes: #433 --- alembic/ddl/impl.py | 2 ++ alembic/testing/requirements.py | 7 ++++++ alembic/util/__init__.py | 2 +- alembic/util/sqla_compat.py | 1 + docs/build/changelog.rst | 9 ++++++++ tests/test_autogen_diffs.py | 40 +++++++++++++++++++++++++++++++++ 6 files changed, 60 insertions(+), 1 deletion(-) diff --git a/alembic/ddl/impl.py b/alembic/ddl/impl.py index 0971c216..39558ab4 100644 --- a/alembic/ddl/impl.py +++ b/alembic/ddl/impl.py @@ -240,6 +240,8 @@ class DefaultImpl(with_metaclass(ImplMeta)): metadata_type = metadata_column.type metadata_impl = metadata_type.dialect_impl(self.dialect) + if isinstance(metadata_impl, sqltypes.Variant): + metadata_impl = metadata_impl.impl.dialect_impl(self.dialect) # work around SQLAlchemy bug "stale value for type affinity" # fixed in 0.7.4 diff --git a/alembic/testing/requirements.py b/alembic/testing/requirements.py index 4468ef20..38527720 100644 --- a/alembic/testing/requirements.py +++ b/alembic/testing/requirements.py @@ -153,6 +153,13 @@ class SuiteRequirements(Requirements): "SQLAlchemy 0.9.4 or greater required" ) + @property + def sqlalchemy_1014(self): + return exclusions.skip_if( + lambda config: not util.sqla_1014, + "SQLAlchemy 1.0.14 or greater required" + ) + @property def sqlalchemy_110(self): return exclusions.skip_if( diff --git a/alembic/util/__init__.py b/alembic/util/__init__.py index bb249dc6..8a857366 100644 --- a/alembic/util/__init__.py +++ b/alembic/util/__init__.py @@ -8,7 +8,7 @@ from .pyfiles import ( # noqa pyc_file_from_path, load_python_file, edit) from .sqla_compat import ( # noqa sqla_07, sqla_079, sqla_08, sqla_083, sqla_084, sqla_09, sqla_092, - sqla_094, sqla_099, sqla_100, sqla_105, sqla_110, sqla_1010) + sqla_094, sqla_099, sqla_100, sqla_105, sqla_110, sqla_1010, sqla_1014) from .exc import CommandError diff --git a/alembic/util/sqla_compat.py b/alembic/util/sqla_compat.py index 57eacd51..e0507f89 100644 --- a/alembic/util/sqla_compat.py +++ b/alembic/util/sqla_compat.py @@ -30,6 +30,7 @@ sqla_100 = _vers >= (1, 0, 0) sqla_105 = _vers >= (1, 0, 5) sqla_1010 = _vers >= (1, 0, 10) sqla_110 = _vers >= (1, 1, 0) +sqla_1014 = _vers >= (1, 0, 14) if sqla_08: from sqlalchemy.sql.expression import TextClause diff --git a/docs/build/changelog.rst b/docs/build/changelog.rst index 9a4b152c..4b7a57d7 100644 --- a/docs/build/changelog.rst +++ b/docs/build/changelog.rst @@ -7,6 +7,15 @@ Changelog :version: 0.9.3 :released: + .. change:: 433 + :tags: bug, autogenerate + :tickets: 433 + + Fixed bug where autogen comparison of a :class:`.Variant` datatype + would not compare to the dialect level type for the "default" + implementation of the :class:`.Variant`, returning the type as changed + between database and table metadata. + .. change:: 431 :tags: bug, tests :tickets: 431 diff --git a/tests/test_autogen_diffs.py b/tests/test_autogen_diffs.py index 239e31fa..39329ccf 100644 --- a/tests/test_autogen_diffs.py +++ b/tests/test_autogen_diffs.py @@ -662,6 +662,46 @@ class CompareTypeSpecificityTest(TestBase): is_(impl.compare_type(Column('x', t2), Column('x', t3)), True) +class AutogenerateVariantCompareTest(AutogenTest, TestBase): + __backend__ = True + + # 1.0.13 and lower fail on Postgresql due to variant / bigserial issue + # #3739 + + __requires__ = ('sqlalchemy_1014', ) + + @classmethod + def _get_db_schema(cls): + m = MetaData() + + Table('sometable', m, + Column( + 'id', + BigInteger().with_variant(Integer, "sqlite"), + primary_key=True), + Column('value', String(50))) + return m + + @classmethod + def _get_model_schema(cls): + m = MetaData() + + Table('sometable', m, + Column( + 'id', + BigInteger().with_variant(Integer, "sqlite"), + primary_key=True), + Column('value', String(50))) + return m + + def test_variant_no_issue(self): + uo = ops.UpgradeOps(ops=[]) + autogenerate._produce_net_changes(self.autogen_context, uo) + + diffs = uo.as_diffs() + eq_(diffs, []) + + class AutogenerateCustomCompareTypeTest(AutogenTest, TestBase): __only_on__ = 'sqlite' -- 2.47.2