Apply DDLCompiler name rules to Index for autogenerate
The autogenerate compare scheme now takes into account the name truncation rules applied by SQLAlchemy's DDL compiler to the names of the :class:`.Index` object, when these names are dynamically truncated due to a too-long identifier name. As the identifier truncation is deterministic, applying the same rule to the metadata name allows correct comparison to the database-derived name. Change-Id: I270fbde4430a41f4bcc7857f1932347d86f07675 Fixes: #421
This commit is contained in:
parent
50469dc261
commit
4cdb25bf5d
|
@ -277,6 +277,9 @@ def _compare_columns(schema, tname, conn_table, metadata_table,
|
|||
|
||||
class _constraint_sig(object):
|
||||
|
||||
def md_name_to_sql_name(self, context):
|
||||
return self.name
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.const == other.const
|
||||
|
||||
|
@ -310,6 +313,9 @@ class _ix_constraint_sig(_constraint_sig):
|
|||
self.sig = tuple(sorted([col.name for col in const.columns]))
|
||||
self.is_unique = bool(const.unique)
|
||||
|
||||
def md_name_to_sql_name(self, context):
|
||||
return sqla_compat._get_index_final_name(context.dialect, self.const)
|
||||
|
||||
@property
|
||||
def column_names(self):
|
||||
return sqla_compat._get_index_column_names(self.const)
|
||||
|
@ -433,7 +439,7 @@ def _compare_indexes_and_uniques(
|
|||
|
||||
# 5. index things by name, for those objects that have names
|
||||
metadata_names = dict(
|
||||
(c.name, c) for c in
|
||||
(c.md_name_to_sql_name(autogen_context), c) for c in
|
||||
metadata_unique_constraints.union(metadata_indexes)
|
||||
if c.name is not None)
|
||||
|
||||
|
|
|
@ -171,3 +171,10 @@ def _get_index_expressions(idx):
|
|||
|
||||
def _get_index_column_names(idx):
|
||||
return [getattr(exp, "name", None) for exp in _get_index_expressions(idx)]
|
||||
|
||||
|
||||
def _get_index_final_name(dialect, idx):
|
||||
if sqla_08:
|
||||
return dialect.ddl_compiler(dialect, None)._prepared_index_name(idx)
|
||||
else:
|
||||
return idx.name
|
||||
|
|
|
@ -7,6 +7,17 @@ Changelog
|
|||
:version: 0.9.2
|
||||
:released:
|
||||
|
||||
.. change:: 421
|
||||
:tags: bug, autogenerate
|
||||
:tickets: 421
|
||||
|
||||
The autogenerate compare scheme now takes into account the name truncation
|
||||
rules applied by SQLAlchemy's DDL compiler to the names of the
|
||||
:class:`.Index` object, when these names are dynamically truncated
|
||||
due to a too-long identifier name. As the identifier truncation is
|
||||
deterministic, applying the same rule to the metadata name allows
|
||||
correct comparison to the database-derived name.
|
||||
|
||||
.. change:: 419
|
||||
:tags: bug environment
|
||||
:tickets: 419
|
||||
|
|
|
@ -979,3 +979,27 @@ class IncludeHooksTest(AutogenFixtureTest, TestBase):
|
|||
eq_(diffs[1][0], 'add_constraint')
|
||||
eq_(diffs[1][1].name, 'uq2')
|
||||
eq_(len(diffs), 2)
|
||||
|
||||
|
||||
class TruncatedIdxTest(AutogenFixtureTest, TestBase):
|
||||
__requires__ = ('sqlalchemy_09', )
|
||||
|
||||
def setUp(self):
|
||||
self.bind = engines.testing_engine()
|
||||
self.bind.dialect.max_identifier_length = 30
|
||||
|
||||
def test_idx_matches_long(self):
|
||||
from alembic.operations.base import conv
|
||||
|
||||
m1 = MetaData()
|
||||
Table(
|
||||
'q', m1,
|
||||
Column('id', Integer, primary_key=True),
|
||||
Column('data', Integer),
|
||||
Index(
|
||||
conv("idx_q_table_this_is_more_than_thirty_characters"),
|
||||
"data")
|
||||
)
|
||||
|
||||
diffs = self._fixture(m1, m1)
|
||||
eq_(diffs, [])
|
||||
|
|
Loading…
Reference in New Issue