A Delta Catalog Table

Writing BookNest's Catalog as a Delta Table

The catalog feed of XML and Its Toolchain, already in booknest-raw (Loading Files into MinIO), becomes a Delta table on MinIO 30,943 with delta-rs, and a daily price feed is merged into it. The MERGE updates a price only when it changed:

catalog_delta.py: XML catalog to Delta on MinIO, then MERGE a price feedPython
"""BookNest's XML catalog (Chapter 2) as a Delta table on MinIO, then a price feed merged."""
import subprocess, xml.etree.ElementTree as ET
import pyarrow as pa
from deltalake import DeltaTable, write_deltalake
from rs_conf import S3
URI = "s3://warehouse/delta/catalog"
xml = subprocess.run(["mc", "cat", "lake/booknest-raw/catalog/booknest-catalog.xml"],
                     capture_output=True, check=True).stdout
books = pa.Table.from_pylist([{"sku": b.findtext("identifier"), "title": b.findtext("title"),
    "genre": b.findtext("subject"), "price": b.findtext("supply/price")}
    for b in ET.fromstring(xml).iter("book")])
books = books.set_column(3, "price", books["price"].cast(pa.decimal128(9, 2)))  # not float
write_deltalake(URI, books, mode="overwrite", storage_options=S3)
feed = pa.table({"sku": ["BN-0002", "BN-0005"],                       # tomorrow's price feed
                 "price": pa.array(["34.50", "16.20"]).cast(pa.decimal128(9, 2))})
m = (DeltaTable(URI, storage_options=S3)
     .merge(feed, "t.sku = s.sku", source_alias="s", target_alias="t")
     .when_matched_update({"price": "s.price"}, predicate="t.price <> s.price")
     .execute())
print({k: v for k, v in m.items() if k.startswith("num_target_rows")})
Output
{'num_target_rows_inserted': 0, 'num_target_rows_updated': 1, 'num_target_rows_deleted': 0,
  'num_target_rows_copied': 5}

One price changed, the unchanged one was skipped by the predicate, and the five other rows were copied into the rewritten file: copy-on-write at file granularity. The cast keeps prices exact decimal(9,2) values, as in the Iceberg 129 tables.