]> git.ipfire.org Git - thirdparty/sqlalchemy/alembic.git/commitdiff
Implement ExecuteSQLOp.to_diff_tuple
authorSebastian Bayer (AE/MFD2-SO) <sebastian.bayer@de.bosch.com>
Thu, 26 Oct 2023 13:18:48 +0000 (09:18 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 26 Oct 2023 14:11:17 +0000 (10:11 -0400)
Repaired :class:`.ExecuteSQLOp` so that it can participate in "diff"
operations; while this object is typically not present in a reflected
operation stream, custom hooks may be adding this construct where it needs
to have the correct ``to_diff_tuple()`` method.  Pull request courtesy
Sebastian Bayer.

Fixes: #1335
Closes: #1336
Pull-request: https://github.com/sqlalchemy/alembic/pull/1336
Pull-request-sha: c5e217e99d0fae87ccc89fc57c71e1c07c57ea97

Change-Id: I303f1a6b1b7bad52f00c6183b77f5e7fe6d0ef37

alembic/operations/ops.py
docs/build/unreleased/1335.rst [new file with mode: 0644]
tests/test_autogen_diffs.py
tests/test_script_production.py

index fe681217520385031b1f6f0c665178a44a503c13..711d7aba33f0136e7752b6311d366fa3883c88c7 100644 (file)
@@ -2539,6 +2539,9 @@ class ExecuteSQLOp(MigrateOperation):
             operations, sqltext, execution_options=execution_options
         )
 
+    def to_diff_tuple(self) -> Tuple[str, Union[Executable, str]]:
+        return ("execute", self.sqltext)
+
 
 class OpContainer(MigrateOperation):
     """Represent a sequence of operations operation."""
diff --git a/docs/build/unreleased/1335.rst b/docs/build/unreleased/1335.rst
new file mode 100644 (file)
index 0000000..ce4ab57
--- /dev/null
@@ -0,0 +1,9 @@
+.. change::
+    :tags: bug, operations
+    :tickets: 1335
+
+    Repaired :class:`.ExecuteSQLOp` so that it can participate in "diff"
+    operations; while this object is typically not present in a reflected
+    operation stream, custom hooks may be adding this construct where it needs
+    to have the correct ``to_diff_tuple()`` method.  Pull request courtesy
+    Sebastian Bayer.
index 2a622aeed614677cf212d0f17c1239eeafd1836c..197bf39a240e03105be88db3a52a482159cb418a 100644 (file)
@@ -696,6 +696,17 @@ class AutogenerateDiffTest(ModelOne, AutogenTest, TestBase):
             ],
         )
 
+    def test_add_execute_sql_op(self):
+        uo = ops.UpgradeOps(ops=[])
+        autogenerate._produce_net_changes(self.autogen_context, uo)
+
+        uo.ops.append(ops.ExecuteSQLOp("STATEMENT"))
+
+        diffs = uo.as_diffs()
+
+        eq_(diffs[-1][0], "execute")
+        eq_(diffs[-1][1], "STATEMENT")
+
 
 class AutogenerateDiffTestWSchema(ModelOne, AutogenTest, TestBase):
     __only_on__ = "postgresql"
index d50f7f50c7097c6d7e8a0c8d40ab2a7a09ceefd8..ccc1a107d3b4fda0bd755e0b709725814a47c938 100644 (file)
@@ -1090,6 +1090,50 @@ class RewriterTest(TestBase):
             "    # ### end Alembic commands ###",
         )
 
+    def test_add_execute_sql(self):
+        writer = autogenerate.Rewriter()
+
+        @writer.rewrites(ops.CreateTableOp)
+        def rewriter_execute_sql(context, revision, op):
+            execute_op = ops.ExecuteSQLOp(sqltext="STATEMENT")
+            return [op, execute_op]
+
+        directives = [
+            ops.MigrationScript(
+                util.rev_id(),
+                ops.UpgradeOps(
+                    ops=[
+                        ops.CreateTableOp(
+                            "test_table",
+                            [sa.Column("id", sa.Integer(), primary_key=True)],
+                        )
+                    ]
+                ),
+                ops.DowngradeOps(ops=[]),
+            )
+        ]
+
+        ctx, rev = mock.Mock(), mock.Mock()
+        writer(ctx, rev, directives)
+
+        eq_(
+            autogenerate.render_python_code(directives[0].upgrade_ops_list[0]),
+            "# ### commands auto generated by Alembic - please adjust! ###\n"
+            "    op.create_table('test_table',\n"
+            "    sa.Column('id', sa.Integer(), nullable=False),\n"
+            "    sa.PrimaryKeyConstraint('id')\n"
+            "    )\n"
+            "    op.execute('STATEMENT')\n"
+            "    # ### end Alembic commands ###",
+        )
+
+        diffs = directives[0].upgrade_ops_list[0].as_diffs()
+
+        eq_(diffs[0][0], "add_table")
+
+        eq_(diffs[1][0], "execute")
+        eq_(diffs[1][1], "STATEMENT")
+
 
 class MultiDirRevisionCommandTest(TestBase):
     def setUp(self):