class _constraint_sig(object):
def md_name_to_sql_name(self, context):
- return self.name
+ return sqla_compat._get_constraint_final_name(
+ self.const, context.dialect
+ )
def __eq__(self, other):
return self.const == other.const
metadata_names = dict(
(c.md_name_to_sql_name(autogen_context), c)
for c in metadata_unique_constraints.union(metadata_indexes)
- if c.name is not None
+ if isinstance(c, _ix_constraint_sig)
+ or sqla_compat._constraint_is_named(c.const, autogen_context.dialect)
)
conn_uniques_by_name = dict((c.name, c) for c in conn_unique_constraints)
)
metadata_indexes_by_sig = dict((ix.sig, ix) for ix in metadata_indexes)
unnamed_metadata_uniques = dict(
- (uq.sig, uq) for uq in metadata_unique_constraints if uq.name is None
+ (uq.sig, uq)
+ for uq in metadata_unique_constraints
+ if not sqla_compat._constraint_is_named(
+ uq.const, autogen_context.dialect
+ )
)
# assumptions:
def _get_index_final_name(dialect, idx):
- # trying to keep the truncation rules totally localized on the
- # SQLA side while also stepping around the quoting issue. Ideally
- # the _prepared_index_name() method on the SQLA side would have
- # a quoting option or the truncation routine would be broken out.
- #
- # test for SQLA quoted_name construct, introduced in
- # 0.9 or thereabouts.
- # this doesn't work in 0.8 and the "quote" option on Index doesn't
- # seem to work in 0.8 either.
+ if sqla_14:
+ return _get_constraint_final_name(idx, dialect)
+
+ # prior to SQLAlchemy 1.4, work around quoting logic to get at the
+ # final compiled name without quotes.
if hasattr(idx.name, "quote"):
# might be quoted_name, might be truncated_name, keep it the
# same
return dialect.ddl_compiler(dialect, None)._prepared_index_name(idx)
+def _get_constraint_final_name(constraint, dialect):
+ if sqla_14:
+ if constraint.name is None:
+ return None
+
+ # for SQLAlchemy 1.4 we would like to have the option to expand
+ # the use of "deferred" names for constraints as well as to have
+ # some flexibility with "None" name and similar; make use of new
+ # SQLAlchemy API to return what would be the final compiled form of
+ # the name for this dialect.
+ return dialect.identifier_preparer.format_constraint(
+ constraint, _alembic_quote=False
+ )
+ else:
+ return constraint.name
+
+
+def _constraint_is_named(constraint, dialect):
+ if sqla_14:
+ if constraint.name is None:
+ return False
+ name = dialect.identifier_preparer.format_constraint(
+ constraint, _alembic_quote=False
+ )
+ return name is not None
+ else:
+ return constraint.name is not None
+
+
def _dialect_supports_comments(dialect):
if sqla_120:
return dialect.supports_comments
--- /dev/null
+.. change::
+ :tags: change, compatibility
+
+ Some internal modifications have been made to how the names of indexes and
+ unique constraints work to make use of new functions added in SQLAlchemy
+ 1.4, so that SQLAlchemy has more flexibility over how naming conventions
+ may be applied to these objects.
from alembic.testing import eq_
from alembic.testing import TestBase
from alembic.testing.env import staging_env
+from alembic.util import sqla_compat
from ._autogen_fixtures import AutogenFixtureTest
py3k = sys.version_info >= (3,)
eq_(diffs[0][0], "add_table")
eq_(diffs[1][0], "add_index")
- eq_(diffs[1][1].name, "ix_extra_foo")
+ eq_(
+ sqla_compat._get_constraint_final_name(
+ diffs[1][1], config.db.dialect
+ ),
+ "ix_extra_foo",
+ )
eq_(diffs[2][0], "add_index")
eq_(diffs[2][1].name, "newtable_idx")
diffs = self._fixture(m1, m2)
eq_(diffs, [])
+ def test_nothing_changed_implicit_uq_w_naming_conv(self):
+ m1 = MetaData(
+ naming_convention={
+ "ix": "ix_%(column_0_label)s",
+ "uq": "uq_%(column_0_label)s",
+ }
+ )
+ m2 = MetaData(
+ naming_convention={
+ "ix": "ix_%(column_0_label)s",
+ "uq": "uq_%(column_0_label)s",
+ }
+ )
+
+ Table(
+ "nothing_changed",
+ m1,
+ Column("id1", Integer, primary_key=True),
+ Column("id2", Integer, primary_key=True),
+ Column("x", String(20), unique=True),
+ mysql_engine="InnoDB",
+ )
+
+ Table(
+ "nothing_changed",
+ m2,
+ Column("id1", Integer, primary_key=True),
+ Column("id2", Integer, primary_key=True),
+ Column("x", String(20), unique=True),
+ mysql_engine="InnoDB",
+ )
+ diffs = self._fixture(m1, m2)
+ eq_(diffs, [])
+
def test_nothing_changed_two(self):
m1 = MetaData()
m2 = MetaData()