learn-analytics-engineering-with-phoebe / Leader session 2 of 6
Learn Analytics Engineering with Phoebe · Leader track · Session 2 of 6

Models as code

Four practices, borrowed wholesale from software engineering, applied to the SQL that now shapes your numbers: version control, review, environments, rollback. Each one prevents a specific failure you have probably lived through. Each one also costs something real, and on a small estate the cost is larger than the benefit. This session gives you both halves honestly, plus the precondition nobody mentions in a vendor meeting: somebody has to actually read the change. A team that will not review gets the entire cost of this and none of the protection.

🟢 Leader track Heads of data · analytics leads · stakeholders No code to write 45 min
0-3 · Welcome 3-16 · The four practices, and what each prevents 16-30 · What it costs, and the precondition 30-42 · Discussion: the review-culture test 42-45 · Q&A
Part 0

What this session is actually deciding

Session a1 established that transformation moved into the warehouse and became SQL that somebody has to own. This session is about the how: the specific working practices that make owning it possible, what each one buys, and what each one costs a team that has never had them.

Keep one framing in mind throughout. None of the four practices below is a feature of dbt or of any other tool. They are software-engineering practices that are forty years old, and the only contribution the tooling makes is to render SQL eligible for them: files on disk, in a repository, that a build step turns into tables. That is why the categories in this session outlive the products, and why a leader who learns them does not have to relearn this when the tool changes.

Everything measured here comes from this course's own project, where the same marketplace warehouse exists twice: once hand-written as 8 SQL files with a 27-check Python validator, once as a dbt project with 23 models, 100 tests, 1 snapshot and 8 declared sources. Both produce settled net revenue of 111,906.48 over 957 orders, AOV 116.93, identical to the cent. The second version is not more accurate. It is more changeable, and this session is about what "more changeable" is worth.

Live - presented in session Self-study - read after class ◆ Discussion - run it with your own team Sources covered
★ What you walk out with today Four practices you can name and defend, the specific failure each one prevents, an honest cost line you can quote to a finance partner, the model count where the argument stops being close, and the single cultural question that determines whether any of it works at your company.
Part 1 · covers software-engineering practice applied to SQL

The four practices, and what each prevents 13 min live

Take each one in turn as a leader would: not "what does it do" but "which meeting does it stop me having". They are worth learning in this order, because each one depends on the one before it.

1 · Version control PREVENTS A definition change becomes a diff somebody reviewed, not a discovery in a dashboard. 2 · Review PREVENTS A wrong grain caught in a pull request costs minutes. Caught in a board pack, it costs trust. 3 · Environments PREVENTS Dev and prod from the same code, so a change can be tried in full before anyone sees it. 4 · Rollback PREVENTS Revert one commit instead of reconstructing from memory what the SQL used to say. None of the four is a dbt feature They are software-engineering practices, forty years old. The tool's only contribution is to make SQL eligible for them: files in a repository that a build step turns into tables. The categories outlive the products.
🔍 Click to zoom - four practices, four specific failures they stop
PracticeWhat it means in practiceWhat it prevents
Version control Every model is a file in a repository. Every change to it is a recorded, attributed, timestamped difference against what it said before, with the author's stated reason attached. The definition change nobody knew about. A change to what a word means arrives as a diff somebody reviewed, rather than as a stakeholder asking on Thursday why the number moved on Tuesday.
Review A change is proposed, read by a second person and discussed before it becomes real. Small, specific, and about one thing, because the diff shows exactly what moved. Expensive discovery. The cheapest place to catch a wrong grain, a double-counting join or a filter that quietly excludes a segment is a pull request, where it costs somebody ten minutes.
Environments The same code builds a development copy and the production copy. A person can build the whole estate with their change in it, look at the resulting numbers, and only then ship. The estate nobody dares change. Hand-written warehouses that cannot be rebuilt anywhere except in production are exactly the ones that freeze, because every change is a live experiment on the business.
Rollback Undo is reverting one recorded change and rebuilding. Not archaeology, not a rewrite, and not a meeting about what the logic used to be. The two-day incident. Recovery time stops depending on whether the person who made the change is available, awake, or still employed here.
LiveReview is the one that carries the others4 min▶

If you only fund one of the four, fund review, because the other three are largely mechanical and review is the only one that requires a human habit. It is also where the money is: the cost of a modelling mistake scales with how far it travels before somebody notices.

  • Caught in review: a colleague spends ten minutes reading a diff and says "this is at order grain, not order-item grain, so the revenue will double-count for multi-line orders". Cost: ten minutes and a slightly awkward comment thread.
  • Caught in a dashboard, a fortnight later: somebody notices revenue looks high. Now it is an investigation, a correction, a decision about whether to restate, and a conversation with everybody who saw the wrong number. Cost: days, spread across people who did not make the mistake.
  • Caught by a stakeholder in a board pack: the number is now a credibility event rather than a bug. Cost: not measurable in hours, and it lands on you rather than on the team.

Nothing about that ladder is specific to data. It is the reason software teams review code, and the reason they did not have to be argued into it twice.

The leader's version of this You do not need to read diffs. You need to know that every change to a model people build on was read by a second person, and to notice when the answer becomes "usually" or "for the important ones". Both of those answers mean no.
LiveEnvironments, and the estate nobody dares change3 min▶

This is the practice leaders under-weight, because it sounds like infrastructure hygiene. It is not. It is the difference between an estate that can evolve and one that has quietly frozen.

Ask yourself what happens today when somebody wants to change how a shared metric is calculated. In an estate with environments, they build the whole thing in a development copy with their change in it, compare the numbers before and after, show somebody, and ship. In an estate without environments, the only way to see the effect of the change is to make it in production and look at the dashboard afterwards.

The second situation does not usually produce disasters. It produces something quieter and more expensive: nobody changes anything. The team accumulates workarounds instead, a parallel table here, a spreadsheet correction there, because a new object beside the old one is safe and editing the old one is not. That is how a warehouse ends up with three revenue tables, none of which anybody is allowed to delete.

This course's project can be rebuilt from nothing in 1.22 seconds, which is a laptop-scale number rather than an enterprise one, but the property it demonstrates is the one that matters: a full rebuild is a routine act rather than an event.

Self-studyWhy version control matters more for definitions than for SQL3 min read▶

There is a version of this argument that is only about engineering tidiness, and it is not the interesting one. The interesting one is about institutional memory.

When a definition lives in a file under version control, three things become true that were not true before. First, the change is attributed: a specific person changed what "settled revenue" means on a specific date. Second, the change has a stated reason, because somebody had to write one to get it merged. Third, the previous version still exists, so "what did this mean in March" is a question with an answer rather than a discussion.

Consider how you would answer an auditor, a regulator or a new chief financial officer asking why a reported figure changed between two quarters. In a hand-written estate the honest answer is that somebody edited a script and the reasoning is in their head. Under version control the answer is a change, an author, a date, a reason and a reviewer. That is not tidiness, that is a governance artifact, and it is the same argument session a3 makes about tests.

Part 2 · the honest half

What it costs, and where the trade flips 9 min live

Any account of this that does not lead with the cost is a sales pitch. The four practices are not free, they are not culturally free either, and there is a real range of estate sizes where adopting them is the wrong decision. Knowing where that range ends is most of the value of this session.

What it costs A build step between an idea and a table A Python dependency to install, pin and upgrade Templating inside the SQL, so SQL alone is no longer enough to read a model A team that has to learn all three at once What it buys Dependency order derived, never maintained Tests that run on every build, not on request One reviewable diff per definition change A full rebuild as a routine act, not an event Documentation generated from the same files Where the trade actually sits Under about 5 models Bad trade. The overhead is most of the work. Somewhere in between Depends entirely on review culture. See Part 3. Past 15 to 20, 2+ editors It stops being close. Fund it.
🔍 Click to zoom - the cost is real, and so is the point where it stops mattering
LiveThe cost line, stated plainly enough to quote4 min▶

Four costs, and it is worth being able to say all four out loud without flinching, because a team that has been sold this without them will resent it later.

  • A build step. There is now a thing that has to run between writing SQL and having a table. It can fail. Somebody has to understand why it failed. On the day of a deadline this is genuinely annoying, and pretending otherwise loses you credibility with the people who feel it.
  • A dependency to manage. The tooling is software: it needs installing, pinning to a version, and upgrading occasionally, and upgrades sometimes require changes. This course's project runs on dbt-core 1.12.0 with dbt-duckdb 1.10.1, and one deprecation had to be fixed during the build. That is normal and it is a real, recurring cost, not a one-off.
  • Templating in the SQL. Models stop being pure SQL. They contain a little templating language that turns a reference into a table name at build time. This is what buys the derived dependency order, and it means SQL fluency alone no longer makes somebody able to read a model. Your analysts will notice this first.
  • A team learning all three at once. The largest cost by a distance, and the one nobody puts on the slide. Version control, review workflow and a build tool, arriving together, at a team whose current workflow is editing a script. Budget a quarter of reduced output, not a training afternoon.
Say this to your team before you decide "We are going to be slower for a quarter and I know it." That sentence buys more goodwill than any amount of enthusiasm about the destination, and it is also true.
LiveFive models versus twenty: why the number matters4 min▶

On five models maintained by one person, all four practices are overhead with almost nothing on the other side. There is no dependency order worth deriving, because the person knows it. There is nobody to review, because there is nobody else. The build step is pure friction, and rollback is "undo my last edit". Adopting the full apparatus here is a real mistake, and it is a mistake made often, usually because somebody read about the modern data stack rather than counted their own models.

Somewhere past fifteen to twenty models with more than one editor, every term in that calculation inverts. Nobody holds the dependency order in their head any more, so it has to be either derived or written down and maintained, and maintained runbooks go stale. Two editors means changes collide, which means review has something to catch. The build step now saves more time than it costs, because rebuilding by hand in the right order is the expensive part.

Two clarifications that matter when you use this number in an argument. It is a range and not a threshold, so treat fifteen to twenty as the zone where you should start actively deciding rather than a line that triggers a purchase. And the model count is the weaker half of the test: the number of editors is the stronger half, because one careful person can hold forty models together for years, and three people editing eight models cannot.

The forward pointer Once you have decided the practices are worth it, the next question is what to buy and what to run yourself, including the Core versus Cloud decision. That is entirely session a4, and it deserves its own forty-five minutes.
Self-studyWhat the hand-written estate could not do3 min read▶

Worth being precise about, because the honest list is shorter than the marketing list and more persuasive for it. The hand-written version of Bazaar is 8 SQL files and a Python validator with 27 checks. It is competent work. What it structurally cannot do:

  • It cannot be built anywhere except where it is built. The script names its tables directly, so there is no cheap way to produce a complete second copy of the estate for a person to try a change in.
  • It does not know what depends on what. The order is the order the statements happen to be in, maintained by a human. Add a model in the wrong place and it silently reads yesterday's data.
  • Its checks run when somebody remembers. Twenty-seven checks that are not attached to the build are twenty-seven checks that run on good days.
  • It cannot answer "what did this used to say". Not because nobody wrote it down, but because there is nowhere for it to be written down.

The dbt version fixes all four, and produces exactly the same 111,906.48. That is the whole trade in one paragraph: no accuracy gain, four structural capabilities, in exchange for the four costs above.

Part 3 · the part that is your job, not the tool's

The cultural precondition, and blast radius 5 min live

Here is the sentence to take out of this session if you take only one. Somebody has to review. Every benefit in Part 1 except rollback depends on a second person actually reading the change, and no tool can supply that. Two organisations can adopt identical tooling and get opposite outcomes, and the variable is not skill.

Same tooling. The only difference is whether anybody reads the diff. A team that reviews Gets all four practices. Mistakes are caught by a colleague in minutes, definitions get argued about before they ship, and two people always understand every model. A team that will not review Pays every cost and collects one benefit. Approvals arrive in seconds without being read, so the pull request is just a slower way to push straight to production. Blast radius, stated honestly Models as code makes a good model cheaper to maintain and a bad model faster to spread everywhere, in seconds, on the next build. One wrong definition in a shared model reaches every mart and every dashboard that depends on it, consistently and immediately. Consistency cuts both ways.
🔍 Click to zoom - the precondition, and the risk that comes with it
LiveHow to tell whether your team will actually review3 min▶

Not by asking, because everybody says yes. Three signals are worth more than the answer:

  • Does anybody currently read anything? Not code, necessarily. A team where two people read each other's dashboard logic before publishing already has the habit and will transfer it. A team where nothing is ever read by a second person will not acquire the habit because a tool arrived.
  • Is there slack in the week? Review is a real time cost that produces nothing visible, so it is the first thing dropped by a team running at capacity. If every hour is committed to delivery, review will be performed rather than done, and performed review is the worst of all worlds because it produces the paperwork of safety without the safety.
  • Does disagreement survive seniority? If a junior analyst can say "this looks wrong to me" to your most senior engineer and expect a real answer, review will work. If not, reviews become approvals, and approvals catch nothing.

All three of those are things you control and the tooling does not. Which is the uncomfortable conclusion of this session: the largest determinant of whether this investment pays off is not the tool, the vendor or the model count. It is whether you have built a team where somebody can say no to a change, and whether you have left them the time to do it.

The cheapest possible start Before any tooling decision, introduce review on your current estate. Two people, one rule: no change to a shared transformation without a second pair of eyes, even if the review happens over a shared screen. If that survives a month, the rest is mechanical. If it does not, no purchase will rescue it.
LiveBlast radius: the risk this creates3 min▶

Close on this rather than on the benefits, because it is the part your risk-minded colleagues will find on their own and it is better coming from you.

A hand-written estate fails slowly and visibly. Somebody's query diverges from somebody else's, people argue in a meeting, and eventually a person digs in and finds the difference. Slow, embarrassing, expensive in aggregate, but the damage is contained by the fact that nothing is really shared.

An estate built as code fails quickly and consistently. One wrong definition in a shared upstream model propagates to every mart and every dashboard downstream of it, on the next build, in seconds. The traceability is genuinely much better and the blast radius is genuinely much larger, and both of those follow from the same property: everything derives from one definition in one place.

So the honest closing sentence of this session is: models as code makes a good model cheaper to maintain and a bad model faster to spread everywhere. That is not an argument against it. It is an argument for the two things that limit the damage: a review habit, which is Part 3, and a test suite that stops a bad build before anybody sees it, which is all of session a3. Formal interfaces between models, so a downstream consumer cannot be broken silently, are builder session b9 and get their leadership treatment in a5.

Discussion · 12 min · everybody talks

The review-culture test ★ run this with your own team

Two exercises, both verbal, both designed for a meeting already on your calendar. The first is a post-mortem of a change you have already made, which is the most honest evidence available. The second is a commitment test, and the point of it is to find out whether the answer is no before you spend money.

Pick a real change, not a hypothetical one. The last definition change that shipped, whatever it was. Hypotheticals get the answer people wish were true.

Walk the four practices against it in order. Where was it written, who read it, was it tried anywhere first, how would you have put it back. Four questions, one change.

Then ask the naming question, and wait through the silence. Who will review every model change, and what will they stop doing to make room. The pause before the answer is the finding.

Record which of the four you already have. Most teams have one and a half. That is your starting point and your honest baseline for the a4 decision.

LiveExercise 1 · Walk one real change through the four practices7 min · run it next week▶

The prompt, word for word

"Take the last change we made to what a number means. Walk me through four things: where was the change written down, who read it before it went live, was it tried anywhere before production, and how would we have put it back if it had been wrong?"

What a good answer sounds like

Four specific answers, even if two of them are bad. "It was a commit on a branch, Sam reviewed it, we did not try it anywhere because we do not have a dev target, and putting it back would be reverting the commit and rebuilding." That team has version control, review and rollback but no environments, which is a common and very fixable shape. The value of the exercise is that it produces a precise gap rather than a general unease, and a precise gap is something you can fund.

The failure mode to listen for

An answer that is really about the outcome rather than the process: "it went fine". Ask again, about the process. The second failure mode is the answer that sounds complete but collapses on the third question, which is almost always environments, because that is the practice teams skip while believing they have adopted everything. Listen for "well, we looked at the numbers afterwards" - that is production being the development environment, said politely.

Why this exercise works better than an audit It is about one change everybody remembers, so nobody has to generalise or defend the whole estate. You will learn more from four answers about one change than from an hour of discussion about practices in the abstract.
LiveExercise 2 · The naming question7 min · run it next week▶

The prompt, word for word

"If we adopt this next quarter, name the person who will read every model change before it ships. Then tell me what that person is going to stop doing to make room for it."

What a good answer sounds like

A name, and a sacrifice. "Priya, and she stops owning the weekly marketing refresh, which moves to Tom." That is a team that has understood the cost. A second good answer is a boundary: "Priya, but only for the shared models, and anything in a personal schema does not need review." That is better than universal review that nobody sustains, because a rule that fits in the week is a rule that survives the quarter.

The failure mode to listen for

"We will all review each other's work." No individual has been made responsible, so review becomes whoever is least busy, which is whoever cares least. The other failure mode is a name with no sacrifice attached: review then gets added on top of a full week, which means it happens on quiet weeks and stops in exactly the busy periods where changes are riskiest and mistakes are most likely to matter.

The number to write down Ask what fraction of a week review will take, get a real answer, and hold it. Ten percent of one senior person is a sane figure for a mid-sized estate. If the answer is "hardly any time", nobody has done it before, and you should plan for the true number rather than the hoped-for one.
Real world

The two Bazaar estates are the cleanest illustration of this that this course can offer, because both exist and both were written carefully. The hand-written version is 8 SQL files plus a 27-check Python validator, and it produces the correct numbers today. The dbt version is 23 models, 100 tests, 1 snapshot and 8 declared sources, builds in 1.22 seconds with PASS=121 and ERROR=0, and produces the same 111,906.48 over the same 957 orders, AOV 116.93, identical to the cent.

What the second one added is entirely in the four practices. Its dependency order is derived rather than maintained, so nobody keeps a runbook: the lineage graph has 32 nodes and 47 edges and no human drew it. Its 100 tests run on every build instead of when somebody remembers. Every definition change is a reviewable diff. And it can be rebuilt from nothing, which is what makes a development copy possible at all.

And the same properties are what make it dangerous. One wrong definition in a shared staging model reaches all 12 marts on the next build, in about a second. The hand-written estate would have got the same thing wrong more slowly, in fewer places, and more visibly. That is the trade you are approving, and the two things that limit it are review culture and the test suite in a3.

Take this away

Questions to ask your data team 7 questions

All seven are answerable without showing you any SQL, and all seven are about process rather than competence, which is why teams answer them honestly.

Ask thisWhy it works
"Show me the last change to a shared model and tell me who read it before it shipped." Tests version control and review in one question, using evidence rather than intent. A team with both answers in twenty seconds. A team without them starts explaining, and the explanation is the answer.
"Can somebody build the whole estate with a change in it, look at the numbers, and only then ship?" The environments question, phrased as a capability rather than a tool. Note whether the answer distinguishes "we can build one model" from "we can build the estate", because only the second one lets you see a knock-on effect.
"If a definition change turned out to be wrong on Friday, what happens on Friday?" Tests rollback as recovery time rather than as a feature. Listen for whether the answer depends on a particular person being available, because that dependency is the actual risk and it usually goes unnamed.
"How much of somebody's week is review, and whose week is it?" Converts a cultural claim into a number and an owner. Zero hours means no review, whatever the workflow diagram says. An unnamed owner means review happens when the week is quiet, which is not when you need it.
"What is the largest number of models one of our transformations produces, and how many people edit it?" Locates you against the fifteen-to-twenty range from Part 2. The editor count is the more important half, and asking for both in one breath stops the conversation collapsing into model count alone.
"If we got one definition wrong upstream, how many dashboards would show the wrong number, and how fast?" The blast radius question. A team that can answer has lineage and understands the risk. A team that cannot answer has the same risk without the visibility, which is strictly worse, and the question surfaces that without an accusation.
"What would we be slower at for the first quarter, and what would we stop doing?" Asks for the adoption cost in the team's own words. If they say nothing will get slower, they have not done this before, and you have just learned the most important thing about the plan you are being asked to approve.
Homework

Before session a3 ◐ 30-40 min total, all conversations

Source material

Sources covered

This page covers:

✓Software-engineering practice applied to SQL - version control, review, environments, rollback, blast radiusParts 1-3 · the four practices, the four costs, and the cultural precondition
✓The community layering conventions - why a stated layer boundary is what makes review cheapPart 1 · as the reason a diff is readable; builder b3 builds the layers
◐The dbt documentation - models, materializations, project configNamed as the mechanism only, no syntax here · builder b1 and b2 run it
◐The dbt documentation - model contracts as a limit on blast radiusPart 3 names the mitigation only · builder b9 builds contracts, leader a5 owns who signs them
◐Kimball & Ross - grain, which is the mistake review most often catchesUsed as the example in Part 1 only; the model itself is learn-data-modeling
◐Continuous integration - what runs automatically on a proposed changeNamed as the natural next step · builder b9 wires it, a3 decides what should block it
Check yourself

Three questions before you go 🎯 ◐ 90 seconds

1 · Your team runs six models, one person edits them, and they are asking to adopt the full models-as-code apparatus. What is the defensible answer?

On six models with one editor there is no dependency order worth deriving and nobody to review, so all four practices are overhead. A "not yet" with a stated trigger keeps the decision alive and stops it becoming a fight later. The editor count is the stronger half of the trigger.

2 · A team adopts version control, environments and rollback, but every pull request is approved within seconds without being read. What have they bought?

Rollback survives without review, so the answer is not "nothing". But every benefit that depends on a second person seeing the change before it ships is gone, and the team is paying the full learning and process cost for it. A leader can supply the review habit; no tool can.

3 · A colleague says moving to models-as-code will reduce the risk of a wrong number reaching a dashboard. How should you correct that?

Traceability improves and blast radius grows, and both follow from the same property: everything derives from one definition in one place. Saying this out loud is what makes the test suite in a3 and the review habit in Part 3 fundable rather than optional.

Leader session 2 cheat sheet · pin this

Version controlA definition change is a diff somebody reviewed, not a discovery in a dashboard. Attributed, dated, with a stated reason.
ReviewThe cheapest place to catch a wrong grain is a pull request. The most expensive is a board pack.
EnvironmentsDev and prod from the same code. Estates that cannot do this are the ones nobody dares change.
RollbackRevert a commit instead of reconstructing what the SQL used to say. Recovery stops depending on one person.
The cost, honestlyA build step, a Python dependency, templating in the SQL, and a team learning all three at once. Budget a slower quarter.
Where it flipsBad trade under five models with one editor. Stops being close past fifteen to twenty with two or more editors.
The preconditionSomebody has to review. A team that will not gets the whole cost and none of the protection.
Blast radiusA good model gets cheaper to maintain; a bad one spreads everywhere in seconds on the next build. Next: a3, what stops it.