]> git.ipfire.org Git - thirdparty/sqlalchemy/alembic.git/commitdiff
differentiate CreateTableOp from model vs. op.create_table()
authorMike Bayer <mike_mp@zzzcomputing.com>
Mon, 24 May 2021 20:14:30 +0000 (16:14 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 24 May 2021 20:22:32 +0000 (16:22 -0400)
Fixed regression caused by just fixed :ticket:`844` that scaled back the
filter for ``unique=True/index=True`` too far such that these directives no
longer worked for the ``op.create_table()`` op, this has been fixed.

Change-Id: Idbed889ef4fbb7b3a944d3f4631f1cae53030316
Fixes: #848
alembic/operations/ops.py
docs/build/unreleased/848.rst [new file with mode: 0644]
tests/test_op.py

index edd13b80fdfb5735e14289e2f3646c85072d1e89..8d300ec9952781d0c50575e1b629af913ac4dc1f 100644 (file)
@@ -945,7 +945,13 @@ class CreateTableOp(MigrateOperation):
     """Represent a create table operation."""
 
     def __init__(
-        self, table_name, columns, schema=None, _namespace_metadata=None, **kw
+        self,
+        table_name,
+        columns,
+        schema=None,
+        _namespace_metadata=None,
+        _constraints_included=False,
+        **kw
     ):
         self.table_name = table_name
         self.columns = columns
@@ -954,6 +960,7 @@ class CreateTableOp(MigrateOperation):
         self.prefixes = kw.pop("prefixes", None)
         self.kw = kw
         self._namespace_metadata = _namespace_metadata
+        self._constraints_included = _constraints_included
 
     def reverse(self):
         return DropTableOp.from_table(
@@ -973,6 +980,13 @@ class CreateTableOp(MigrateOperation):
             list(table.c) + list(table.constraints),
             schema=table.schema,
             _namespace_metadata=_namespace_metadata,
+            # given a Table() object, this Table will contain full Index()
+            # and UniqueConstraint objects already constructed in response to
+            # each unique=True / index=True flag on a Column.  Carry this
+            # state along so that when we re-convert back into a Table, we
+            # skip unique=True/index=True so that these constraints are
+            # not doubled up. see #844 #848
+            _constraints_included=True,
             comment=table.comment,
             prefixes=table._prefixes,
             **table.kwargs
@@ -987,7 +1001,7 @@ class CreateTableOp(MigrateOperation):
             schema=self.schema,
             prefixes=self.prefixes,
             comment=self.comment,
-            _constraints_included=True,
+            _constraints_included=self._constraints_included,
             **self.kw
         )
 
@@ -1111,7 +1125,8 @@ class DropTableOp(MigrateOperation):
             self.table_name,
             *cols_and_constraints,
             schema=self.schema,
-            _constraints_included=True,
+            _constraints_included=bool(self._reverse)
+            and self._reverse._constraints_included,
             **self.table_kw
         )
         return t
diff --git a/docs/build/unreleased/848.rst b/docs/build/unreleased/848.rst
new file mode 100644 (file)
index 0000000..6596e6f
--- /dev/null
@@ -0,0 +1,7 @@
+.. change::
+    :tags: bug, regression, op directives
+    :tickets: 848
+
+    Fixed regression caused by just fixed :ticket:`844` that scaled back the
+    filter for ``unique=True/index=True`` too far such that these directives no
+    longer worked for the ``op.create_table()`` op, this has been fixed.
index 63d3e965379e33e6de907e64c33b91e83eaa722e..1b829383880dfe79e3b56c3d41fc02d3d9e82dc9 100644 (file)
@@ -877,6 +877,36 @@ class OpTest(TestBase):
         uq = [c for c in t1.constraints if isinstance(c, UniqueConstraint)]
         eq_(uq[0].name, "uq_1")
 
+    def test_create_table_unique_flag(self):
+        context = op_fixture()
+        t1 = op.create_table(
+            "some_table",
+            Column("id", Integer, primary_key=True),
+            Column("foo_id", Integer, unique=True),
+        )
+        context.assert_(
+            "CREATE TABLE some_table (id INTEGER NOT NULL, foo_id INTEGER, "
+            "PRIMARY KEY (id), UNIQUE (foo_id))"
+        )
+
+        uq = [c for c in t1.constraints if isinstance(c, UniqueConstraint)]
+        assert uq
+
+    def test_create_table_index_flag(self):
+        context = op_fixture()
+        t1 = op.create_table(
+            "some_table",
+            Column("id", Integer, primary_key=True),
+            Column("foo_id", Integer, index=True),
+        )
+        context.assert_(
+            "CREATE TABLE some_table (id INTEGER NOT NULL, foo_id INTEGER, "
+            "PRIMARY KEY (id))",
+            "CREATE INDEX ix_some_table_foo_id ON some_table (foo_id)",
+        )
+
+        assert t1.indexes
+
     def test_create_table_index(self):
         context = op_fixture()
         t1 = op.create_table(