As asked
Write a PySpark snippet that reads a staging DataFrame with potential duplicates on (user_id, event_id), deduplicates keeping the latest record by event_ts, then merges into an Iceberg target table updating existing rows and inserting new ones.
Sample answer outline
The candidate should use Window.partitionBy('event_id').orderBy(desc('event_ts')) with row_number() to deduplicate, filter to row_number == 1, then use the Iceberg MERGE INTO SQL extension (registered via the Iceberg Spark extensions config) or the DataFrameWriterV2 overwritePartitions API. They should handle matched (update) and not-matched (insert) clauses correctly. Note: DeltaTable is a Delta Lake class and has no equivalent in Iceberg; the correct Iceberg merge entry point is the MERGE INTO SQL statement or the V2 write API.
Reference implementation (python)
from pyspark.sql import functions as F
from pyspark.sql.window import Window
w = Window.partitionBy("event_id").orderBy(F.desc("event_ts"))
deduped = (
staging
.withColumn("rn", F.row_number().over(w))
.filter(F.col("rn") == 1)
.drop("rn")
)
deduped.createOrReplaceTempView("staged")
spark.sql("""
MERGE INTO prod.events t
USING staged s ON t.event_id = s.event_id
WHEN MATCHED THEN UPDATE SET *
WHEN NOT MATCHED THEN INSERT *
""")Expect these follow-ups
- How would you handle the case where event_ts can be identical for two records with the same event_id?
- What is the performance difference between using MERGE INTO SQL and the Iceberg DataFrameWriterV2 overwritePartitions?