A watermark table
One Delta table that says, for each table, how far the last good run got.
Merging all of bronze into silver on every run works while bronze is small. As it grows, each run reads more rows to change fewer. A watermark fixes that: it remembers how far the last good run got, so the next run reads only what came after.
What to measure by
The watermark needs a column that only goes up as new rows arrive. In the bronze table from the lakehouse course, every row has _loaded_at, the time it was landed. That is the column to use: it belongs to the platform, not to the source, so a source that sends old dates cannot fool it.
The table
In a notebook attached to the lakehouse, create one Delta table for every watermark the lakehouse will ever need:
spark.sql("""
CREATE TABLE IF NOT EXISTS etl_watermark (
table_name STRING,
last_value TIMESTAMP,
updated_at TIMESTAMP
) USING DELTA
""")One row per table you load this way. Add the row for orders, starting far in the past so the first run reads everything:
from pyspark.sql import functions as F
if spark.table("etl_watermark").filter("table_name = 'orders'").isEmpty():
spark.createDataFrame(
[("orders",)], "table_name STRING"
).select(
"table_name",
F.lit("1900-01-01").cast("timestamp").alias("last_value"),
F.current_timestamp().alias("updated_at"),
).write.mode("append").saveAsTable("etl_watermark")The check before the insert means the cell can run again without adding a second row.
Read it
Every run starts by asking how far the last one got:
last = (spark.table("etl_watermark")
.filter("table_name = 'orders'")
.first()["last_value"])
print(f"Reading orders loaded after {last}")Run it now: it prints the start date, 1 January 1900.
Why a table and not a file
A Delta table can be read and changed by any notebook, pipeline or SQL query in the workspace, keeps its history and is changed in one step or not at all. You can also look at it from the lakehouse's SQL analytics endpoint:
SELECT table_name, last_value, updated_at
FROM etl_watermark;