]> git.ipfire.org Git - thirdparty/sqlalchemy/alembic.git/commitdiff
implement SQLite RENAME TABLE w schema syntax
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 12 Jul 2022 23:36:57 +0000 (19:36 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 12 Jul 2022 23:38:56 +0000 (19:38 -0400)
Fixed bug where the SQLite implementation of
:meth:`.Operations.rename_table` would render an explicit schema name for
both the old and new table name, which while is the standard ALTER syntax,
is not accepted by SQLite's syntax which doesn't support a rename across
schemas. In particular, the syntax issue would prevent batch mode from
working for SQLite databases that made use of attached databases (which are
treated as "schemas" in SQLAlchemy).

Change-Id: I02d8163b39cd33568c7528158218828ff0813695
Fixes: #1065
alembic/ddl/sqlite.py
docs/build/unreleased/1065.rst [new file with mode: 0644]
tests/test_sqlite.py

index 9b387664c78d9f1a8e2de67dbfcd3f02b73be51b..f986c32c3a50fcb6de1a03e2e23cdeb71baba3d6 100644 (file)
@@ -11,12 +11,17 @@ from sqlalchemy import cast
 from sqlalchemy import JSON
 from sqlalchemy import schema
 from sqlalchemy import sql
+from sqlalchemy.ext.compiler import compiles
 
+from .base import alter_table
+from .base import format_table_name
+from .base import RenameTable
 from .impl import DefaultImpl
 from .. import util
 
 if TYPE_CHECKING:
     from sqlalchemy.engine.reflection import Inspector
+    from sqlalchemy.sql.compiler import DDLCompiler
     from sqlalchemy.sql.elements import Cast
     from sqlalchemy.sql.elements import ClauseElement
     from sqlalchemy.sql.schema import Column
@@ -178,6 +183,16 @@ class SQLiteImpl(DefaultImpl):
             )
 
 
+@compiles(RenameTable, "sqlite")
+def visit_rename_table(
+    element: "RenameTable", compiler: "DDLCompiler", **kw
+) -> str:
+    return "%s RENAME TO %s" % (
+        alter_table(compiler, element.table_name, element.schema),
+        format_table_name(compiler, element.new_table_name, None),
+    )
+
+
 # @compiles(AddColumn, 'sqlite')
 # def visit_add_column(element, compiler, **kw):
 #    return "%s %s" % (
diff --git a/docs/build/unreleased/1065.rst b/docs/build/unreleased/1065.rst
new file mode 100644 (file)
index 0000000..42a97a6
--- /dev/null
@@ -0,0 +1,11 @@
+.. change::
+    :tags: bug, sqlite
+    :tickets: 1065
+
+    Fixed bug where the SQLite implementation of
+    :meth:`.Operations.rename_table` would render an explicit schema name for
+    both the old and new table name, which while is the standard ALTER syntax,
+    is not accepted by SQLite's syntax which doesn't support a rename across
+    schemas. In particular, the syntax issue would prevent batch mode from
+    working for SQLite databases that made use of attached databases (which are
+    treated as "schemas" in SQLAlchemy).
index 3915343d1bf3339258fa21c221292eb27dcd2656..b8edeaaf1a18fcb0513a7a01338540e59d86ba5a 100644 (file)
@@ -81,6 +81,11 @@ class SQLiteTest(TestBase):
         op.add_column("t1", Column("c1", Integer, comment="c1 comment"))
         context.assert_("ALTER TABLE t1 ADD COLUMN c1 INTEGER")
 
+    def test_rename_table_w_schema(self):
+        context = op_fixture("sqlite")
+        op.rename_table("old_name", "new_name", schema="my_schema")
+        context.assert_("ALTER TABLE my_schema.old_name RENAME TO new_name")
+
 
 class SQLiteDefaultCompareTest(TestBase):
     __only_on__ = "sqlite"