99 {% set merge_schema = optional_args .get (" merge_schema" , true) %}
1010 {% set bucket_count = optional_args .get (" bucket_count" ) %}
1111 {% set field_delimiter = optional_args .get (" field_delimiter" ) %}
12+ {% set table_type = optional_args .get (" table_type" , " " ) %}
13+ {% set extra_table_properties = optional_args .get (" extra_table_properties" ) %}
14+ {% set use_iceberg_write_to = optional_args .get (" use_iceberg_write_to" , false) %}
1215 {% set spark_ctas = optional_args .get (" spark_ctas" , " " ) %}
1316
1417import pyspark
@@ -25,7 +28,48 @@ def materialize(spark_session, df, target_relation):
2528 msg = f" {type(df)} is not a supported type for dbt Python materialization"
2629 raise Exception(msg)
2730
28- {% if spark_ctas|length > 0 %}
31+ {% if use_iceberg_write_to %}
32+ import re
33+ from pyspark .sql import functions as F
34+
35+ def _parse_iceberg_partition(expr_str):
36+ expr_str = expr_str .strip ()
37+ m = re .match (r" (\w+)\((.+)\)" , expr_str)
38+ if not m:
39+ return F .col (expr_str)
40+ func = m .group (1 ).lower ()
41+ args = [a .strip () for a in m .group (2 ).split(" ," )]
42+ if func in (" day" , " days" ):
43+ return F .days (F .col (args[0 ]))
44+ if func in (" month" , " months" ):
45+ return F .months (F .col (args[0 ]))
46+ if func in (" year" , " years" ):
47+ return F .years (F .col (args[0 ]))
48+ if func in (" hour" , " hours" ):
49+ return F .hours (F .col (args[0 ]))
50+ if func == " bucket" :
51+ return F .bucket (int (args[1 ]), F .col (args[0 ]))
52+ if func == " truncate" :
53+ return F .truncate (int (args[1 ]), F .col (args[0 ]))
54+ raise ValueError(f" Unknown Iceberg partition transform: {func}" )
55+
56+ _writer = df .writeTo (" {{ target_relation.schema | replace('\" ' , ' ` ') }}.{{ target_relation.identifier | replace('\" ', '` ' ) }}")
57+ _writer = _writer.using("iceberg")
58+ _writer = _writer.tableProperty("location", "{{ location }}/")
59+ {% if extra_table_properties is not none %}
60+ {% for prop_name, prop_value in extra_table_properties.items() %}
61+ _writer = _writer.tableProperty("{{ prop_name }}", "{{ prop_value }}")
62+ {% endfor %}
63+ {% endif %}
64+ {% if partitioned_by is not none %}
65+ _writer = _writer.partitionedBy(
66+ {%- for part_expr in partitioned_by %}
67+ _parse_iceberg_partition("{{ part_expr }}"){{ "," if not loop.last }}
68+ {%- endfor %}
69+ )
70+ {% endif %}
71+ _writer.createOrReplace()
72+ {% elif spark_ctas|length > 0 %}
2973 df.createOrReplaceTempView("{{ target_relation.schema}}_{{ target_relation.identifier }}_tmpvw")
3074 spark_session.sql("""
3175 {{ spark_ctas }}
0 commit comments