Skip to content

Commit b3409dd

Browse files
authored
Fix: Support of the table renaming in Snowflake and Databricks (#2509)
1 parent be8511b commit b3409dd

File tree

6 files changed

+54
-16
lines changed

6 files changed

+54
-16
lines changed

sqlmesh/core/engine_adapter/databricks.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import pandas as pd
77
from sqlglot import exp
88

9+
from sqlmesh.core.engine_adapter.mixins import RenameTableFullTargetNameMixin
910
from sqlmesh.core.engine_adapter.shared import (
1011
CatalogSupport,
1112
DataObject,
@@ -29,7 +30,7 @@
2930
"_get_data_objects": CatalogSupport.REQUIRES_SET_CATALOG,
3031
}
3132
)
32-
class DatabricksEngineAdapter(SparkEngineAdapter):
33+
class DatabricksEngineAdapter(SparkEngineAdapter, RenameTableFullTargetNameMixin):
3334
DIALECT = "databricks"
3435
INSERT_OVERWRITE_STRATEGY = InsertOverwriteStrategy.INSERT_OVERWRITE
3536
SUPPORTS_CLONING = True

sqlmesh/core/engine_adapter/mixins.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,3 +246,18 @@ def _truncate_table(self, table_name: TableName) -> None:
246246
if self._connection_pool.is_transaction_active:
247247
return self.execute(exp.Delete(this=exp.to_table(table_name)))
248248
super()._truncate_table(table_name)
249+
250+
251+
class RenameTableFullTargetNameMixin(EngineAdapter):
252+
def _rename_table(
253+
self,
254+
old_table_name: TableName,
255+
new_table_name: TableName,
256+
) -> None:
257+
old_table = exp.to_table(old_table_name)
258+
new_table = exp.to_table(new_table_name)
259+
if not new_table.db and old_table.db:
260+
# In MySQL and Snowflake you need to provide the full target table name.
261+
# Therefore we use the old schema name if one is not provided explicitly in the new name.
262+
new_table.set("db", old_table.args["db"])
263+
return super()._rename_table(old_table, new_table)

sqlmesh/core/engine_adapter/mysql.py

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
LogicalMergeMixin,
1111
NonTransactionalTruncateMixin,
1212
PandasNativeFetchDFSupportMixin,
13+
RenameTableFullTargetNameMixin,
1314
)
1415
from sqlmesh.core.engine_adapter.shared import (
1516
CommentCreationTable,
@@ -30,6 +31,7 @@ class MySQLEngineAdapter(
3031
LogicalMergeMixin,
3132
PandasNativeFetchDFSupportMixin,
3233
NonTransactionalTruncateMixin,
34+
RenameTableFullTargetNameMixin,
3335
):
3436
DEFAULT_BATCH_SIZE = 200
3537
DIALECT = "mysql"
@@ -142,16 +144,3 @@ def _create_column_comments(
142144
f"Column comments for table '{table.alias_or_name}' not registered - this may be due to limited permissions.",
143145
exc_info=True,
144146
)
145-
146-
def _rename_table(
147-
self,
148-
old_table_name: TableName,
149-
new_table_name: TableName,
150-
) -> None:
151-
old_table = exp.to_table(old_table_name)
152-
new_table = exp.to_table(new_table_name)
153-
if not new_table.db and old_table.db:
154-
# In MySQL you need to provide the full target table name.
155-
# Therefore we use the old schema name if one is not provided explicitly in the new name.
156-
new_table.set("db", old_table.args["db"])
157-
return super()._rename_table(old_table, new_table)

sqlmesh/core/engine_adapter/snowflake.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@
1010
from sqlglot.optimizer.qualify_columns import quote_identifiers
1111

1212
from sqlmesh.core.dialect import to_schema
13-
from sqlmesh.core.engine_adapter.mixins import GetCurrentCatalogFromFunctionMixin
13+
from sqlmesh.core.engine_adapter.mixins import (
14+
GetCurrentCatalogFromFunctionMixin,
15+
RenameTableFullTargetNameMixin,
16+
)
1417
from sqlmesh.core.engine_adapter.shared import (
1518
CatalogSupport,
1619
DataObject,
@@ -32,7 +35,7 @@
3235
"drop_schema": CatalogSupport.REQUIRES_SET_CATALOG,
3336
}
3437
)
35-
class SnowflakeEngineAdapter(GetCurrentCatalogFromFunctionMixin):
38+
class SnowflakeEngineAdapter(GetCurrentCatalogFromFunctionMixin, RenameTableFullTargetNameMixin):
3639
DIALECT = "snowflake"
3740
SUPPORTS_MATERIALIZED_VIEWS = True
3841
SUPPORTS_MATERIALIZED_VIEW_SCHEMA = True

tests/core/engine_adapter/test_databricks.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,18 @@ def test_get_current_database(make_mocked_engine_adapter: t.Callable):
103103

104104
assert adapter.get_current_database() == "test_database"
105105
assert to_sql_calls(adapter) == ["SELECT CURRENT_DATABASE()"]
106+
107+
108+
def test_rename_table(make_mocked_engine_adapter: t.Callable):
109+
adapter = make_mocked_engine_adapter(DatabricksEngineAdapter)
110+
111+
adapter.rename_table("test_schema.old_name", "new_name")
112+
adapter.rename_table("test_schema.old_name", "new_test_schema.new_name")
113+
adapter.rename_table("old_name", "new_name")
114+
115+
sql_calls = to_sql_calls(adapter)
116+
assert sql_calls == [
117+
"ALTER TABLE `test_schema`.`old_name` RENAME TO `test_schema`.`new_name`",
118+
"ALTER TABLE `test_schema`.`old_name` RENAME TO `new_test_schema`.`new_name`",
119+
"ALTER TABLE `old_name` RENAME TO `new_name`",
120+
]

tests/core/engine_adapter/test_snowflake.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,18 @@ def test_comments(make_mocked_engine_adapter: t.Callable, mocker: MockerFixture)
143143
"""COMMENT ON TABLE "test_table" IS 'table description'""",
144144
"""ALTER TABLE "test_table" ALTER COLUMN "a" COMMENT 'a column description'""",
145145
]
146+
147+
148+
def test_rename_table(make_mocked_engine_adapter: t.Callable, mocker: MockerFixture):
149+
adapter = make_mocked_engine_adapter(SnowflakeEngineAdapter)
150+
151+
adapter.rename_table("test_schema.old_name", "new_name")
152+
adapter.rename_table("test_schema.old_name", "new_test_schema.new_name")
153+
adapter.rename_table("old_name", "new_name")
154+
155+
sql_calls = to_sql_calls(adapter)
156+
assert sql_calls == [
157+
'ALTER TABLE "test_schema"."old_name" RENAME TO "test_schema"."new_name"',
158+
'ALTER TABLE "test_schema"."old_name" RENAME TO "new_test_schema"."new_name"',
159+
'ALTER TABLE "old_name" RENAME TO "new_name"',
160+
]

0 commit comments

Comments
 (0)