Run a job twice, safely
A real job runs every day. Sometimes it fails and runs again. Sometimes you run old days again on purpose.
This chapter makes a job safe to run more than once. It reads only new data, and it never stores the same row twice.
The source is the orders table of the app, with one extra column, updated_at:
| order_id | status | amount | updated_at |
|---|---|---|---|
| 101 | paid | 40.00 | 2026-01-03 |
| 102 | paid | 25.00 | 2026-01-10 |
| 103 | refunded | 60.00 | 2026-01-11 |
| 104 | paid | 15.50 | 2026-01-15 |
| 105 | pending | None | 2026-01-20 |
| 106 | paid | 80.00 | 2026-01-21 |
updated_at is the date the row last changed. It is made up for this chapter, and equals the order date until a row changes.
source = [
{"order_id": 101, "status": "paid", "amount": "40.00", "updated_at": "2026-01-03"},
# ... orders 102 to 106 in the same shape ...
]Data Pipeline chapter 12, Incremental Processing & Backfills, explains these ideas with SQL. This chapter builds them in Python.
