summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2022-07-12 19:36:57 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2022-07-12 19:38:56 -0400
commit8033c78a52b25a5145557a21630d10a34f2209e5 (patch)
treeba2674ccfd4db9d5f7ed9b5cb0474430d08bcf18
parent4fbf99a6ad9f022888ddf709d1e9744d19a76ca6 (diff)
downloadalembic-8033c78a52b25a5145557a21630d10a34f2209e5.tar.gz
implement SQLite RENAME TABLE w schema syntax
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
-rw-r--r--alembic/ddl/sqlite.py15
-rw-r--r--docs/build/unreleased/1065.rst11
-rw-r--r--tests/test_sqlite.py5
3 files changed, 31 insertions, 0 deletions
diff --git a/alembic/ddl/sqlite.py b/alembic/ddl/sqlite.py
index 9b38766..f986c32 100644
--- a/alembic/ddl/sqlite.py
+++ b/alembic/ddl/sqlite.py
@@ -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
index 0000000..42a97a6
--- /dev/null
+++ b/docs/build/unreleased/1065.rst
@@ -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).
diff --git a/tests/test_sqlite.py b/tests/test_sqlite.py
index 3915343..b8edeaa 100644
--- a/tests/test_sqlite.py
+++ b/tests/test_sqlite.py
@@ -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"