Skip to content

Commit d048a5c

Browse files
jecolvinclaude
andcommitted
Address PR review feedback for Iceberg clone
- Harden SHOW TABLES fallback: add IN SCHEMA keyword and filter by exact name match to avoid LIKE wildcard false positives - Use SNOWFLAKE_TEST_ICEBERG_EXTERNAL_VOLUME env var for test portability - Extract copy_state/run_and_save_state to shared module-level functions Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent fce30f2 commit d048a5c

File tree

2 files changed

+27
-38
lines changed

2 files changed

+27
-38
lines changed

dbt-snowflake/src/dbt/include/snowflake/macros/materializations/clone.sql

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@
2323

2424
{#- Cache miss: query Snowflake directly -#}
2525
{%- set show_sql -%}
26-
show tables like '{{ relation.identifier }}' in {{ relation.database }}.{{ relation.schema }}
26+
show tables like '{{ relation.identifier }}' in schema {{ relation.database }}.{{ relation.schema }}
2727
{%- endset -%}
2828
{%- set results = run_query(show_sql) -%}
29-
{%- if results and results | length > 0 -%}
30-
{{ return(results.columns.get('is_iceberg').values()[0] in ('Y', 'YES')) }}
31-
{%- endif -%}
29+
{%- for row in results -%}
30+
{%- if row['name'] == relation.identifier -%}
31+
{{ return(row['is_iceberg'] in ('Y', 'YES')) }}
32+
{%- endif -%}
33+
{%- endfor -%}
3234
{{ return(false) }}
3335
{% endmacro %}

dbt-snowflake/tests/functional/adapter/dbt_clone/test_dbt_clone.py

Lines changed: 21 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,19 @@ def clean_up(self, project):
2727
pass
2828

2929

30+
def copy_state(project_root):
31+
state_path = os.path.join(project_root, "state")
32+
if not os.path.exists(state_path):
33+
os.makedirs(state_path)
34+
shutil.copyfile(f"{project_root}/target/manifest.json", f"{project_root}/state/manifest.json")
35+
36+
37+
def run_and_save_state(project_root):
38+
results = run_dbt(["run"])
39+
assert len(results) == 1
40+
copy_state(project_root)
41+
42+
3043
table_model_1_sql = """
3144
{{ config(
3245
materialized='table',
@@ -55,23 +68,9 @@ def profiles_config_update(self, dbt_profile_target, unique_schema, other_schema
5568
outputs["otherschema"]["schema"] = other_schema
5669
return {"test": {"outputs": outputs, "target": "default"}}
5770

58-
def copy_state(self, project_root):
59-
state_path = os.path.join(project_root, "state")
60-
if not os.path.exists(state_path):
61-
os.makedirs(state_path)
62-
shutil.copyfile(
63-
f"{project_root}/target/manifest.json", f"{project_root}/state/manifest.json"
64-
)
65-
66-
def run_and_save_state(self, project_root, with_snapshot=False):
67-
results = run_dbt(["run"])
68-
assert len(results) == 1
69-
70-
self.copy_state(project_root)
71-
7271
def test_can_clone_transient_table(self, project, other_schema):
7372
project.create_test_schema(other_schema)
74-
self.run_and_save_state(project.project_root)
73+
run_and_save_state(project.project_root)
7574

7675
clone_args = [
7776
"clone",
@@ -85,13 +84,15 @@ def test_can_clone_transient_table(self, project, other_schema):
8584
assert len(results) == 1
8685

8786

88-
iceberg_table_model_sql = """
89-
{{ config(
87+
ICEBERG_EXTERNAL_VOLUME = os.getenv("SNOWFLAKE_TEST_ICEBERG_EXTERNAL_VOLUME", "s3_iceberg_snow")
88+
89+
iceberg_table_model_sql = f"""
90+
{{{{ config(
9091
materialized='table',
9192
table_format='iceberg',
92-
external_volume='s3_iceberg_snow',
93+
external_volume='{ICEBERG_EXTERNAL_VOLUME}',
9394
base_location_subpath='clone_test',
94-
) }}
95+
) }}}}
9596
9697
select 1 as id
9798
"""
@@ -115,23 +116,9 @@ def profiles_config_update(self, dbt_profile_target, unique_schema, other_schema
115116
outputs["otherschema"]["schema"] = other_schema
116117
return {"test": {"outputs": outputs, "target": "default"}}
117118

118-
def copy_state(self, project_root):
119-
state_path = os.path.join(project_root, "state")
120-
if not os.path.exists(state_path):
121-
os.makedirs(state_path)
122-
shutil.copyfile(
123-
f"{project_root}/target/manifest.json", f"{project_root}/state/manifest.json"
124-
)
125-
126-
def run_and_save_state(self, project_root):
127-
results = run_dbt(["run"])
128-
assert len(results) == 1
129-
130-
self.copy_state(project_root)
131-
132119
def test_can_clone_iceberg_table(self, project, other_schema):
133120
project.create_test_schema(other_schema)
134-
self.run_and_save_state(project.project_root)
121+
run_and_save_state(project.project_root)
135122

136123
clone_args = [
137124
"clone",

0 commit comments

Comments
 (0)