Skip to content

Commit 3a3e9b1

Browse files
committed
feat: add conditional_merge support to to_iceberg
1 parent 033ad7d commit 3a3e9b1

1 file changed

Lines changed: 24 additions & 7 deletions

File tree

awswrangler/athena/_write_iceberg.py

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,8 @@ def _validate_args(
240240
mode: Literal["append", "overwrite", "overwrite_partitions"],
241241
partition_cols: list[str] | None,
242242
merge_cols: list[str] | None,
243-
merge_condition: Literal["update", "ignore"],
243+
merge_condition: Literal["update", "ignore", "conditional_merge"],
244+
conditional_merge_string: str | None,
244245
) -> None:
245246
if df.empty is True:
246247
raise exceptions.EmptyDataFrame("DataFrame cannot be empty.")
@@ -260,9 +261,13 @@ def _validate_args(
260261
"When mode is 'overwrite_partitions' merge_cols must not be specified."
261262
)
262263

263-
if merge_cols and merge_condition not in ["update", "ignore"]:
264+
if merge_cols and merge_condition not in ["update", "ignore", "conditional_merge"]:
264265
raise exceptions.InvalidArgumentValue(
265-
f"Invalid merge_condition: {merge_condition}. Valid values: ['update', 'ignore']"
266+
f"Invalid merge_condition: {merge_condition}. Valid values: ['update', 'ignore', 'conditional_merge']"
267+
)
268+
if merge_cols and merge_condition == "conditional_merge" and not conditional_merge_string:
269+
raise exceptions.InvalidArgumentCombination(
270+
"When merge_condition is 'conditional_merge', conditional_merge_string must be specified."
266271
)
267272

268273

@@ -300,7 +305,8 @@ def _merge_iceberg(
300305
table: str,
301306
source_table: str,
302307
merge_cols: list[str] | None = None,
303-
merge_condition: Literal["update", "ignore"] = "update",
308+
merge_condition: Literal["update", "ignore", "conditional_merge"] = "update",
309+
conditional_merge_string: str | None = None,
304310
merge_match_nulls: bool = False,
305311
partition_cols: list[str] | None = None,
306312
kms_key: str | None = None,
@@ -332,7 +338,9 @@ def _merge_iceberg(
332338
333339
https://docs.aws.amazon.com/athena/latest/ug/merge-into-statement.html
334340
merge_condition: str, optional
335-
The condition to be used in the MERGE INTO statement. Valid values: ['update', 'ignore'].
341+
The condition to be used in the MERGE INTO statement. Valid values: ['update', 'ignore', 'conditional_merge'].
342+
conditional_merge_string: str, optional
343+
The condition string to be used if merge_condition is 'conditional_merge'.
336344
merge_match_nulls: bool, optional
337345
Instruct whether to have nulls in the merge condition match other nulls
338346
partition_cols: List[str], optional
@@ -364,6 +372,10 @@ def _merge_iceberg(
364372
if merge_condition == "update":
365373
match_condition = f"""WHEN MATCHED THEN
366374
UPDATE SET {", ".join([f'"{x}" = source."{x}"' for x in df.columns])}"""
375+
elif merge_condition == "conditional_merge":
376+
match_condition = f"""WHEN MATCHED AND
377+
{conditional_merge_string} THEN
378+
UPDATE SET {", ".join([f'"{x}" = source."{x}"' for x in df.columns])}"""
367379
else:
368380
match_condition = ""
369381

@@ -417,7 +429,8 @@ def to_iceberg( # noqa: PLR0913
417429
table_location: str | None = None,
418430
partition_cols: list[str] | None = None,
419431
merge_cols: list[str] | None = None,
420-
merge_condition: Literal["update", "ignore"] = "update",
432+
merge_condition: Literal["update", "ignore", "conditional_merge"] = "update",
433+
conditional_merge_string: str | None = None,
421434
merge_match_nulls: bool = False,
422435
keep_files: bool = True,
423436
data_source: str | None = None,
@@ -467,8 +480,10 @@ def to_iceberg( # noqa: PLR0913
467480
468481
https://docs.aws.amazon.com/athena/latest/ug/merge-into-statement.html
469482
merge_condition
470-
The condition to be used in the MERGE INTO statement. Valid values: ['update', 'ignore'].
483+
The condition to be used in the MERGE INTO statement. Valid values: ['update', 'ignore', 'conditional_merge'].
471484
Default is ``update``.
485+
conditional_merge_string
486+
The condition string to be used if merge_condition is 'conditional_merge'.
472487
merge_match_nulls
473488
Instruct whether to have nulls in the merge condition match other nulls.
474489
keep_files
@@ -556,6 +571,7 @@ def to_iceberg( # noqa: PLR0913
556571
partition_cols=partition_cols,
557572
merge_cols=merge_cols,
558573
merge_condition=merge_condition,
574+
conditional_merge_string=conditional_merge_string,
559575
)
560576

561577
glue_table_settings = glue_table_settings if glue_table_settings else {}
@@ -681,6 +697,7 @@ def to_iceberg( # noqa: PLR0913
681697
source_table=temp_table,
682698
merge_cols=merge_cols,
683699
merge_condition=merge_condition,
700+
conditional_merge_string=conditional_merge_string,
684701
merge_match_nulls=merge_match_nulls,
685702
partition_cols=partition_cols,
686703
kms_key=kms_key,

0 commit comments

Comments
 (0)