From: Mike Bayer Date: Tue, 19 Jul 2022 16:01:50 +0000 (-0400) Subject: add docs for naming convention bypass case X-Git-Tag: rel_1_9_0~13 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=873027160f88af277b73223e9fe33bfba315532f;p=thirdparty%2Fsqlalchemy%2Falembic.git add docs for naming convention bypass case Change-Id: I8d604eaab7865466b8a7008693621c00f954397d References: #453 --- diff --git a/docs/build/naming.rst b/docs/build/naming.rst index 5ec81e30..b1b383ee 100644 --- a/docs/build/naming.rst +++ b/docs/build/naming.rst @@ -145,6 +145,12 @@ If we define our models using a :class:`~sqlalchemy.schema.MetaData` as above, t naming convention dictionary will be used to provide names for all constraints and indexes. +.. seealso:: + + :ref:`sqla:constraint_naming_conventions` - SQLAlchemy overview of naming + convention support + + .. _autogen_naming_conventions: Integration of Naming Conventions into Operations, Autogenerate @@ -162,7 +168,7 @@ used:: meta = MetaData(naming_convention={ "ix": "ix_%(column_0_label)s", "uq": "uq_%(table_name)s_%(column_0_name)s", - "ck": "ck_%(table_name)s_%(constraint_name)s", + "ck": "ck_%(table_name)s_`%(constraint_name)s`", "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s", "pk": "pk_%(table_name)s" }) @@ -211,5 +217,50 @@ tokenized:: def upgrade(): op.create_unique_constraint(op.f('uq_const_x'), 'some_table', 'x') +This :meth:`.Operations.f` construct may be used explicitly in order to +bypass naming conventions, as illustrated in the next section. + +Bypassing the Naming Convention for CREATE and DROP Operations +--------------------------------------------------------------- + +When using constraint naming conventions, in particular if the +``%(constraint_name)s`` token is in use, the constraint name used with +methods such as :meth:`.Operations.create_check_constraint` and :meth:`.Operations.drop_constraint` +with a matching :paramref:`.Operations.type_` will **include the naming convention** +unless additional directives are in use. + +Given a configuration in ``env.py`` as:: + + target_metadata = MetaData(naming_convention={ + "ix": "ix_%(column_0_label)s", + "uq": "uq_%(table_name)s_%(column_0_name)s", + "ck": "ck_%(table_name)s_`%(constraint_name)s`", + "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s", + "pk": "pk_%(table_name)s" + }) + # ... + + def run_migrations_online(): + + # ... + + context.configure( + connection=connection, + target_metadata=target_metadata + ) + + +The following operation will drop a CHECK constraint named +``ck_t1_some_check_const``:: + + >>> op.drop_constraint("some_check_const", "t1", type_="check") + ALTER TABLE t1 DROP CONSTRAINT ck_t1_some_check_const + +In order to apply the operation while **bypassing** the configured naming +convention, use the :meth:`.Operations.f` construct. This produces a string +expression that will not be tokenized:: + + >>> op.drop_constraint(op.f("some_check_const"), "t1", type_="check") + ALTER TABLE t1 DROP CONSTRAINT some_check_const + -For more detail on the naming convention feature, see :ref:`sqla:constraint_naming_conventions`. diff --git a/tests/test_op_naming_convention.py b/tests/test_op_naming_convention.py index 0cc22afa..b0fa765e 100644 --- a/tests/test_op_naming_convention.py +++ b/tests/test_op_naming_convention.py @@ -158,3 +158,23 @@ class AutoNamingConventionTest(TestBase): "ALTER TABLE t1 ADD COLUMN c1 BOOLEAN NOT NULL", "ALTER TABLE t1 ADD CONSTRAINT foo CHECK (c1 IN (0, 1))", ) + + def test_drop_check_constraint_plain(self): + context = op_fixture( + naming_convention={"ck": "ck_%(table_name)s_%(constraint_name)s"} + ) + + op.drop_constraint("foo_bar_bat", "t1", type_="check") + context.assert_("ALTER TABLE t1 DROP CONSTRAINT ck_t1_foo_bar_bat") + + def test_drop_check_constraint_opf(self): + context = op_fixture( + naming_convention={"ck": "ck_%(table_name)s_%(constraint_name)s"} + ) + + op.drop_constraint( + op.f("some_specific_foo_bar_bat"), "t1", type_="check" + ) + context.assert_( + "ALTER TABLE t1 DROP CONSTRAINT some_specific_foo_bar_bat" + )