diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-07-19 12:01:50 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-07-19 12:01:50 -0400 |
commit | 873027160f88af277b73223e9fe33bfba315532f (patch) | |
tree | a7cd1d326be0e80011617f370b8b0cdd185fd330 | |
parent | 54d5953be781b1d213557940c6f5960a8d1068dc (diff) | |
download | alembic-873027160f88af277b73223e9fe33bfba315532f.tar.gz |
add docs for naming convention bypass case
Change-Id: I8d604eaab7865466b8a7008693621c00f954397d
References: #453
-rw-r--r-- | docs/build/naming.rst | 55 | ||||
-rw-r--r-- | tests/test_op_naming_convention.py | 20 |
2 files changed, 73 insertions, 2 deletions
diff --git a/docs/build/naming.rst b/docs/build/naming.rst index 5ec81e3..b1b383e 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 0cc22af..b0fa765 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" + ) |