From: Nicolas CANIART Date: Sun, 13 Mar 2022 16:39:40 +0000 (-0400) Subject: Fix duplicated constraints when using expressions X-Git-Tag: rel_1_7_7~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ce6144efc6648986733fb9bbb981e95a4a739f61;p=thirdparty%2Fsqlalchemy%2Falembic.git Fix duplicated constraints when using expressions Fixed issue where using :meth:`.Operations.create_table` in conjunction with a :class:`.CheckConstraint` that referred to table-bound :class:`.Column` objects rather than string expressions would be added to the parent table twice, resulting in an incorrect DDL sequence. Pull request courtesy Nicolas CANIART. Fixes: #1004 Closes: #1005 Pull-request: https://github.com/sqlalchemy/alembic/pull/1005 Pull-request-sha: 2fe5c5297bcde990096571a047039c451aa876f6 Change-Id: I2bf48701968fe59a6766f8f8879320b1bfd75774 --- diff --git a/alembic/operations/schemaobj.py b/alembic/operations/schemaobj.py index c8fab933..0a27920b 100644 --- a/alembic/operations/schemaobj.py +++ b/alembic/operations/schemaobj.py @@ -214,7 +214,8 @@ class SchemaObjects: constraints = [ sqla_compat._copy(elem, target_table=t) - if getattr(elem, "parent", None) is not None + if getattr(elem, "parent", None) is not t + and getattr(elem, "parent", None) is not None else elem for elem in columns if isinstance(elem, (Constraint, Index)) diff --git a/docs/build/unreleased/1004.rst b/docs/build/unreleased/1004.rst new file mode 100644 index 00000000..b6a6908a --- /dev/null +++ b/docs/build/unreleased/1004.rst @@ -0,0 +1,9 @@ +.. change:: + :tags: bug, operations + :tickets: 1004 + + Fixed issue where using :meth:`.Operations.create_table` in conjunction + with a :class:`.CheckConstraint` that referred to table-bound + :class:`.Column` objects rather than string expressions would be added to + the parent table twice, resulting in an incorrect DDL sequence. Pull + request courtesy Nicolas CANIART. diff --git a/tests/test_op.py b/tests/test_op.py index 11d2c1b9..677b7bc0 100644 --- a/tests/test_op.py +++ b/tests/test_op.py @@ -882,6 +882,27 @@ class OpTest(TestBase): ck = [c for c in t1.constraints if isinstance(c, CheckConstraint)] eq_(ck[0].name, "ck_1") + def test_create_table_with_check_constraint_with_expr(self): + context = op_fixture() + foo_id = Column("foo_id", Integer) + t1 = op.create_table( + "some_table", + Column("id", Integer, primary_key=True), + foo_id, + CheckConstraint(foo_id > 5, name="ck_1"), + ) + context.assert_( + "CREATE TABLE some_table (" + "id INTEGER NOT NULL, " + "foo_id INTEGER, " + "PRIMARY KEY (id), " + "CONSTRAINT ck_1 CHECK (foo_id > 5))" + ) + + ck = [c for c in t1.constraints if isinstance(c, CheckConstraint)] + eq_(ck[0].name, "ck_1") + eq_(len(ck), 1) + def test_create_table_unique_constraint(self): context = op_fixture() t1 = op.create_table(