Where the pipeline stands
Daybreak's pipeline now extracts, moves, stores, transforms, and processes data at any scale it will realistically see (b2-b8). It works - on good days. This session is about the bad days: the pipeline running unattended when a source silently changes shape, or a batch arrives half-corrupt. Building a pipeline that survives those moments is the last engineering skill before the capstone, and it is where you hand the running system to the operations world.
Where pipelines break: the three seams 7 min live
A pipeline is a chain of handoffs, and every handoff is a seam under tension. The stages themselves rarely fail - your GROUP BY does not spontaneously break. What breaks is the assumption at a seam: that the source still has the columns you expect, that the data is the type it claims, that a run either fully finishes or fully rolls back. Name the seams and you know exactly where to build your defenses.
LiveSchema drift, bad data, partial failure4 min▶
Three failure modes cover most 3am pages:
- Schema drift: the source team adds, renames, or drops a column and tells no one. Your pipeline either crashes or, worse, keeps running against the wrong shape and produces silently wrong numbers.
- Bad data: nulls in a key, duplicate rows from a re-delivered batch, a date stored as unparseable text. The data arrives but violates what downstream assumes.
- Partial failure: a run dies after writing half its output. Re-run it and you double-count; leave it and the target is corrupt. This is why idempotency matters.
The silent rename. An upstream team renamed customer_id to cust_id in a release. The pipeline did not crash - it read the missing column as all nulls, joined nothing, and served a dashboard showing revenue had collapsed to zero. Finance panicked for a day. A one-line schema check at the seam would have failed the run loudly instead.
Defend the seams: quarantine, do not crash 6 min live
Good pipelines expect bad input. Instead of trusting the feed and crashing when it lies, you build checks into the pipe: assert the shape is what you agreed, cast defensively so bad values become nulls rather than exceptions, route unparseable rows to a quarantine table, and make every run safe to repeat. The goal is a pipeline that degrades gracefully - it flags the problem and keeps the good data flowing.
-- simulate a messy feed: real orders plus two malformed rows
CREATE OR REPLACE TABLE raw_feed AS
SELECT order_id, order_date FROM orders
UNION ALL
VALUES (9001, 'not-a-date'), (9002, '2026-13-40');
-- TRY_CAST returns NULL on failure instead of throwing - the good rows survive
SELECT count(*) AS total_rows,
count(TRY_CAST(order_date AS DATE)) AS good_dates,
count(*) - count(TRY_CAST(order_date AS DATE)) AS quarantined
FROM raw_feed;
Self-studyThe data contract, in concept3 min read▶
A data contract is a written, agreed-upon promise between the team that produces data and you, the team that consumes it. It pins down the shape (which columns, which types), the meaning (what status = 'completed' actually implies), and the service level (how fresh, how often, who to page when it breaks). It turns "the source changed and broke us" into "the source violated the contract" - a conversation with an owner, not a mystery.
- Schema + semantics + SLA: the three parts of a useful contract. Shape alone is not enough; you need agreed meaning and freshness too.
- It makes drift someone's job. With a contract, a breaking change has an owner and a process, not just a downstream victim.
- Enforce it at the seam. A schema check at ingestion is a contract test. It fails the run loudly the moment reality drifts from the promise.
CREATE OR REPLACE TABLE or delete-then-insert for a partition rather than blind appends, so a retry after a partial failure is always safe.
The handoff to DataOps 4 min live
This seam is also the boundary of the course. Data engineering builds the resilient pipeline and emits the signals (row counts, quarantine counts, a clear pass or fail). DataOps operates it: schedules the runs, monitors the signals, alerts a human when something drifts, and tests changes in CI before they ship. Build versus operate - two crafts meeting at one line.
Self-studyWhat lives in the sibling course, not here2 min read▶
You will not write orchestration code in this track - no DAG definitions, no CI configuration, no alerting rules. That is deliberate: those belong to learn-dataops, which operates the pipeline you build here. What you owe the operators is a pipeline that is easy to run on a schedule (idempotent), easy to watch (it emits counts and a clear pass or fail), and easy to reason about when it breaks (bad data is quarantined and logged, not silently dropped).
Build a defensive ingest ★ 12 min · everyone builds
One script, one seam defended. A messy feed arrives with two malformed rows. You will cast defensively, filter the unparseable rows into a clean table, and count what was quarantined - proving a bad row does not kill the run, it just gets set aside.
Simulate the feed: union the real orders with two rows carrying broken dates - the reality a source can hand you.
Defend: TRY_CAST the date and keep only rows that parse, building a clean table the rest of the pipeline can trust.
Prove it: count rows in, rows kept, and rows quarantined. The run survives; the bad data is accounted for.
-- 1) a messy incoming feed: real orders + two malformed rows
CREATE OR REPLACE TABLE raw_feed AS
SELECT order_id, customer_id, order_date, status, channel FROM orders
UNION ALL
VALUES (9001, 99, 'not-a-date', 'completed', 'web'),
(9002, 3, '2026-13-40', 'completed', 'app');
-- 2) defensive transform: keep only rows whose date parses
CREATE OR REPLACE TABLE clean_orders AS
SELECT order_id, customer_id,
TRY_CAST(order_date AS DATE) AS order_date,
status, channel
FROM raw_feed
WHERE TRY_CAST(order_date AS DATE) IS NOT NULL;
-- 3) prove the bad rows were quarantined, not fatal
SELECT (SELECT count(*) FROM raw_feed) AS rows_in,
(SELECT count(*) FROM clean_orders) AS rows_kept,
(SELECT count(*) FROM raw_feed)
- (SELECT count(*) FROM clean_orders) AS quarantined;
Quarantine beats crash, every time. A pipeline that dies on the first bad row blocks all the good data behind it and pages you at 3am. A pipeline that sets aside the bad rows, keeps the good ones flowing, and reports the count lets you fix the source in the morning while the business keeps running on clean data. Graceful degradation is the whole game.
Your turn: harden the seam ★ 10 min · build your own
Two hands-on checks and one boundary question. Each editor starts from Daybreak's raw source. Write the guard, run it, read the result - this is the defensive loop you will use for every pipeline.
LiveQ1 · A schema and null check on the keys3 min▶
-- naming the columns asserts they exist, and the counts check for null keys
SELECT count(*) AS total,
count(*) FILTER (WHERE order_id IS NULL) AS null_order_id,
count(*) FILTER (WHERE customer_id IS NULL) AS null_customer_id,
count(*) FILTER (WHERE order_date IS NULL) AS null_order_date
FROM orders;
LiveQ2 · Dedupe a re-delivered batch, keep the latest4 min▶
-- simulate a re-delivered batch: two duplicate order_ids with a newer date
CREATE OR REPLACE TABLE dup_feed AS
SELECT order_id, order_date, status FROM orders
UNION ALL
SELECT order_id, '2026-06-30', 'refunded' FROM orders WHERE order_id IN (1001, 1002);
-- keep only the latest row per order_id
WITH ranked AS (
SELECT order_id, order_date, status,
row_number() OVER (PARTITION BY order_id
ORDER BY order_date DESC) AS rn
FROM dup_feed
)
SELECT order_id, order_date, status
FROM ranked
WHERE rn = 1
ORDER BY order_id
LIMIT 10;
Self-studyQ3 · What belongs to DE, what belongs to DataOps3 min▶
No SQL - a boundary exercise. At this seam, sort each responsibility into build (DE) or operate (DataOps):
- DE builds: the TRY_CAST guard, the quarantine table, the schema assertion, the idempotent write, and the counts the pipeline emits. The resilience is in the code.
- DataOps operates: running the pipeline nightly, watching the quarantine count, paging someone when it spikes, and gating a change through CI before it reaches production.
The test: if it is a property of the pipeline itself, it is DE. If it is about running and watching the pipeline over time, it is DataOps. Build the seam here; operate it in learn-dataops.
Try it yourself - this week ◐ 20-30 min total
- Pick one pipeline you own. Name its three seams (source-to-ingest, ingest-to-transform, transform-to-serve) and which failure mode each is most exposed to.
- Add a TRY_CAST quarantine step to Demo 1 for a second column (say a numeric field), and report both quarantine counts.
- Draft a one-paragraph data contract for a source you depend on: its columns, their meanings, and how fresh you need it.
- For a pipeline at work, ask: could I re-run today's job right now without double-counting? If not, that step is not idempotent yet.
- List which of your current reliability tasks are really DataOps, and note them as candidates for the learn-dataops course.
Official sources covered
This session teaches the reliability undercurrent of Reis & Housley's Fundamentals of Data Engineering and the source-reliability material from the DeepLearning.AI Data Engineering Professional Certificate, run on a live engine. Certificates, cloud labs, and videos stay on the official platforms. This page covers:
Three questions before you go 🎯 ◐ 90 seconds
1 · What is schema drift?
Schema drift is an unannounced change to the shape of the source - a column added, renamed, or dropped. It either crashes the pipeline or, worse, produces silently wrong results. A schema check at the seam catches it loudly.
2 · What is a data contract?
A data contract pins down the shape (columns and types), the semantics (what values mean), and the SLA (freshness, ownership). It turns a breaking change from a downstream mystery into a producer's responsibility.
3 · At this seam, which task belongs to DataOps rather than data engineering?
DE builds the resilient pipeline (guards, quarantine, idempotency). DataOps operates it - scheduling, monitoring the emitted signals, and alerting. If it is about running and watching over time, it is DataOps.