Your first Delta table
Writing one, reading it back, changing it, and looking at the history that makes it a table.
The point of this lesson is not the syntax. It is watching the log change.
Write it
df = spark.read.csv("/Volumes/main/raw/sales/", header=True, inferSchema=True)
df.write.format("delta").saveAsTable("main.bronze.sales")
Two lines, and you now have a table rather than a folder. Query it:
SELECT count(*) FROM main.bronze.sales;
Change it
UPDATE main.bronze.sales SET region = 'South' WHERE region = 'south';
On a plain folder of files that statement is not possible at all. Here it is ordinary — and underneath, nothing was edited in place. New files were written and a new version was committed.
Look at what actually happened
This is the lesson:
DESCRIBE HISTORY main.bronze.sales;
You get one row per version: what operation ran, when, by whom, and how many rows and files it touched. Your write is version 0; your update is version 1.
And you can go back:
SELECT count(*) FROM main.bronze.sales VERSION AS OF 0;
Spend a minute on that. The reason "why is this number different from yesterday" is usually unanswerable is that most systems have no version 0 to look at. Here you can read the old one and diff it.
inferSchema is a convenience, and convenience is the risk
inferSchema=True samples the file and guesses types. It is fine while you are
poking around. In a job that runs every morning it is a slow, silent trap: the day
a column that has always been numeric arrives with one value of "N/A", the
inferred type changes, and everything downstream that expected a number gets text.
Declare the schema explicitly for anything scheduled. It is more typing once, and it converts a class of 6am mystery into an error message.
Try this
Write a small table, update a row, delete a row, then DESCRIBE HISTORY and read
every version back with VERSION AS OF. Confirm for yourself that the old versions
really are still there — do not take this lesson's word for it.