-
Notifications
You must be signed in to change notification settings - Fork 179
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for Iceberg table format in Dynamic Tables (#1183)
* add support for iceberg dynamic tables * remove is_dynamic-related guards as that is ga now * simplify dynamic table testing * add iceberg dynamic tables to existing dynamic table tests * add standard incremental tables into the relation swap scenarios * account for the fact that snowflake does not support renaming iceberg relations * account for all scenarios when swapping relation types, including those which currently require a full refresh * make it clearer which scenarios are included in each run and why by pulling the criteria into one function --------- Co-authored-by: Mila Page <[email protected]>
- Loading branch information
1 parent
423111f
commit 0521395
Showing
15 changed files
with
593 additions
and
66 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
kind: Features | ||
body: Add support for Iceberg table format in Dynamic Tables | ||
time: 2024-09-17T10:05:05.609859-04:00 | ||
custom: | ||
Author: mikealfare | ||
Issue: "1183" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,17 @@ | ||
from dbt.adapters.snowflake.relation_configs.catalog import ( | ||
SnowflakeCatalogConfig, | ||
SnowflakeCatalogConfigChange, | ||
) | ||
from dbt.adapters.snowflake.relation_configs.dynamic_table import ( | ||
SnowflakeDynamicTableConfig, | ||
SnowflakeDynamicTableConfigChangeset, | ||
SnowflakeDynamicTableRefreshModeConfigChange, | ||
SnowflakeDynamicTableWarehouseConfigChange, | ||
SnowflakeDynamicTableTargetLagConfigChange, | ||
) | ||
from dbt.adapters.snowflake.relation_configs.formats import TableFormat | ||
from dbt.adapters.snowflake.relation_configs.policies import ( | ||
SnowflakeIncludePolicy, | ||
SnowflakeQuotePolicy, | ||
SnowflakeRelationType, | ||
) | ||
from dbt.adapters.snowflake.relation_configs.formats import TableFormat |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
from dataclasses import dataclass | ||
from typing import Any, Dict, Optional, TYPE_CHECKING, Set | ||
|
||
if TYPE_CHECKING: | ||
import agate | ||
|
||
from dbt.adapters.relation_configs import ( | ||
RelationConfigChange, | ||
RelationResults, | ||
RelationConfigValidationMixin, | ||
RelationConfigValidationRule, | ||
) | ||
from dbt.adapters.contracts.relation import RelationConfig | ||
from dbt_common.exceptions import DbtConfigError | ||
from typing_extensions import Self | ||
|
||
from dbt.adapters.snowflake.relation_configs.base import SnowflakeRelationConfigBase | ||
from dbt.adapters.snowflake.relation_configs.formats import TableFormat | ||
|
||
|
||
@dataclass(frozen=True, eq=True, unsafe_hash=True) | ||
class SnowflakeCatalogConfig(SnowflakeRelationConfigBase, RelationConfigValidationMixin): | ||
""" | ||
This config follow the specs found here: | ||
https://docs.snowflake.com/en/sql-reference/sql/create-iceberg-table | ||
https://docs.snowflake.com/en/sql-reference/sql/create-dynamic-table#create-dynamic-iceberg-table | ||
The following parameters are configurable by dbt: | ||
- table_format: format for interfacing with the table, e.g. default, iceberg | ||
- external_volume: name of the external volume in Snowflake | ||
- base_location: the directory within the external volume that contains the data | ||
*Note*: This directory can’t be changed after you create a table. | ||
The following parameters are not currently configurable by dbt: | ||
- name: snowflake | ||
""" | ||
|
||
table_format: Optional[TableFormat] = TableFormat.default() | ||
name: Optional[str] = "SNOWFLAKE" | ||
external_volume: Optional[str] = None | ||
base_location: Optional[str] = None | ||
|
||
@property | ||
def validation_rules(self) -> Set[RelationConfigValidationRule]: | ||
return { | ||
RelationConfigValidationRule( | ||
(self.table_format == "default") | ||
or (self.table_format == "iceberg" and self.base_location is not None), | ||
DbtConfigError("Please provide a `base_location` when using iceberg"), | ||
), | ||
RelationConfigValidationRule( | ||
(self.table_format == "default") | ||
or (self.table_format == "iceberg" and self.name == "SNOWFLAKE"), | ||
DbtConfigError( | ||
"Only Snowflake catalogs are currently supported when using iceberg" | ||
), | ||
), | ||
} | ||
|
||
@classmethod | ||
def from_dict(cls, config_dict: Dict[str, Any]) -> Self: | ||
kwargs_dict = { | ||
"name": config_dict.get("name"), | ||
"external_volume": config_dict.get("external_volume"), | ||
"base_location": config_dict.get("base_location"), | ||
} | ||
if table_format := config_dict.get("table_format"): | ||
kwargs_dict["table_format"] = TableFormat(table_format) | ||
return super().from_dict(kwargs_dict) | ||
|
||
@classmethod | ||
def parse_relation_config(cls, relation_config: RelationConfig) -> Dict[str, Any]: | ||
|
||
if relation_config.config.extra.get("table_format") is None: | ||
return {} | ||
|
||
config_dict = { | ||
"table_format": relation_config.config.extra.get("table_format"), | ||
"name": "SNOWFLAKE", # this is not currently configurable | ||
} | ||
|
||
if external_volume := relation_config.config.extra.get("external_volume"): | ||
config_dict["external_volume"] = external_volume | ||
|
||
if base_location := relation_config.config.extra.get("base_location_subpath"): | ||
config_dict["base_location"] = base_location | ||
|
||
return config_dict | ||
|
||
@classmethod | ||
def parse_relation_results(cls, relation_results: RelationResults) -> Dict[str, Any]: | ||
# this try block can be removed once enable_iceberg_materializations is retired | ||
try: | ||
catalog_results: "agate.Table" = relation_results["catalog"] | ||
except KeyError: | ||
# this happens when `enable_iceberg_materializations` is turned off | ||
return {} | ||
|
||
if len(catalog_results) == 0: | ||
# this happens when the dynamic table is a standard dynamic table (e.g. not iceberg) | ||
return {} | ||
|
||
# for now, if we get catalog results, it's because this is an iceberg table | ||
# this is because we only run `show iceberg tables` to get catalog metadata | ||
# this will need to be updated once this is in `show objects` | ||
catalog: "agate.Row" = catalog_results.rows[0] | ||
config_dict = { | ||
"table_format": "iceberg", | ||
"name": catalog.get("catalog_name"), | ||
"external_volume": catalog.get("external_volume_name"), | ||
"base_location": catalog.get("base_location"), | ||
} | ||
|
||
return config_dict | ||
|
||
|
||
@dataclass(frozen=True, eq=True, unsafe_hash=True) | ||
class SnowflakeCatalogConfigChange(RelationConfigChange): | ||
context: Optional[SnowflakeCatalogConfig] = None | ||
|
||
@property | ||
def requires_full_refresh(self) -> bool: | ||
return True |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
79 changes: 73 additions & 6 deletions
79
dbt/include/snowflake/macros/relations/dynamic_table/create.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.