From 98a0e3fb28f9f5dea6242ecd3b1062abc49914af Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sat, 5 Dec 2015 15:02:20 -0500 Subject: [PATCH] - Added a type-level comparator that distinguishes :class:`.Integer`, :class:`.BigInteger`, and :class:`.SmallInteger` types and dialect-specific types; these all have "Integer" affinity so previously all compared as the same. fixes #341 --- alembic/ddl/impl.py | 16 +++++++++++- docs/build/changelog.rst | 9 +++++++ tests/test_autogen_diffs.py | 50 ++++++++++++++++++++++++++++++++++++- 3 files changed, 73 insertions(+), 2 deletions(-) diff --git a/alembic/ddl/impl.py b/alembic/ddl/impl.py index ac3493bc..d87a2fcb 100644 --- a/alembic/ddl/impl.py +++ b/alembic/ddl/impl.py @@ -337,7 +337,21 @@ def _numeric_compare(t1, t2): t1.scale is not None and t1.scale != t2.scale ) + + +def _integer_compare(t1, t2): + t1_small_or_big = ( + 'S' if isinstance(t1, sqltypes.SmallInteger) + else 'B' if isinstance(t1, sqltypes.BigInteger) else 'I' + ) + t2_small_or_big = ( + 'S' if isinstance(t2, sqltypes.SmallInteger) + else 'B' if isinstance(t2, sqltypes.BigInteger) else 'I' + ) + return t1_small_or_big != t2_small_or_big + _type_comparators = { sqltypes.String: _string_compare, - sqltypes.Numeric: _numeric_compare + sqltypes.Numeric: _numeric_compare, + sqltypes.Integer: _integer_compare } diff --git a/docs/build/changelog.rst b/docs/build/changelog.rst index 15c5f0cc..d9b8de5b 100644 --- a/docs/build/changelog.rst +++ b/docs/build/changelog.rst @@ -6,6 +6,15 @@ Changelog .. changelog:: :version: 0.8.4 + .. change:: + :tags: bug, autogenerate + :tickets: 341 + + Added a type-level comparator that distinguishes :class:`.Integer`, + :class:`.BigInteger`, and :class:`.SmallInteger` types and + dialect-specific types; these all have "Integer" affinity so previously + all compared as the same. + .. change:: :tags: bug, batch :tickets: 338 diff --git a/tests/test_autogen_diffs.py b/tests/test_autogen_diffs.py index 690f4773..6887058f 100644 --- a/tests/test_autogen_diffs.py +++ b/tests/test_autogen_diffs.py @@ -3,7 +3,8 @@ import sys from sqlalchemy import MetaData, Column, Table, Integer, String, Text, \ Numeric, CHAR, ForeignKey, INTEGER, Index, UniqueConstraint, \ TypeDecorator, CheckConstraint, text, PrimaryKeyConstraint, \ - ForeignKeyConstraint + ForeignKeyConstraint, VARCHAR, DECIMAL, DateTime, BigInteger, BIGINT, \ + SmallInteger from sqlalchemy.types import NULLTYPE from sqlalchemy.engine.reflection import Inspector @@ -554,6 +555,53 @@ class AutogenerateDiffTestWSchema(ModelOne, AutogenTest, TestBase): eq_(diffs[10][3].name, 'pw') +class CompareTypeSpecificityTest(TestBase): + def _fixture(self): + from alembic.ddl import impl + from sqlalchemy.engine import default + + return impl.DefaultImpl( + default.DefaultDialect(), None, False, True, None, {}) + + def test_string(self): + t1 = String(30) + t2 = String(40) + t3 = VARCHAR(30) + t4 = Integer + + impl = self._fixture() + is_(impl.compare_type(Column('x', t3), Column('x', t1)), False) + is_(impl.compare_type(Column('x', t3), Column('x', t2)), True) + is_(impl.compare_type(Column('x', t3), Column('x', t4)), True) + + def test_numeric(self): + t1 = Numeric(10, 5) + t2 = Numeric(12, 5) + t3 = DECIMAL(10, 5) + t4 = DateTime + + impl = self._fixture() + is_(impl.compare_type(Column('x', t3), Column('x', t1)), False) + is_(impl.compare_type(Column('x', t3), Column('x', t2)), True) + is_(impl.compare_type(Column('x', t3), Column('x', t4)), True) + + def test_integer(self): + t1 = Integer() + t2 = SmallInteger() + t3 = BIGINT() + t4 = String() + t5 = INTEGER() + t6 = BigInteger() + + impl = self._fixture() + is_(impl.compare_type(Column('x', t5), Column('x', t1)), False) + is_(impl.compare_type(Column('x', t3), Column('x', t1)), True) + is_(impl.compare_type(Column('x', t3), Column('x', t6)), False) + is_(impl.compare_type(Column('x', t3), Column('x', t2)), True) + is_(impl.compare_type(Column('x', t5), Column('x', t2)), True) + is_(impl.compare_type(Column('x', t1), Column('x', t4)), True) + + class AutogenerateCustomCompareTypeTest(AutogenTest, TestBase): __only_on__ = 'sqlite' -- 2.47.2