DV Digest ยท Learn

DIGEST Data Vault Workbook

Workbook: front page

Course DIGEST Data Vault Course

1. What the workbook is

The textbook teaches; the workbook is where you practice. After each lesson from lesson 2 on, the textbook sends you here for its lab: a small increment of the same vault, built in your own branch and your own environment, which merges into qa beside the teacher’s work. Your increments add what the teacher’s do not have. From time to time the workbook also carries a defect drill: a symptom reported from qa, for you to trace, test and fix.

2. Your environment

What Yours
Branch rayserrano/dig-574-labs, started from the teacher’s branch as a one-time exception. Rebase it onto qa now: the teacher’s pull request #2 merged on 2026-10-26, and qa has since gained requests #3 to #6. Your labs continue into the second release
dbt Your own dbt, already configured, building as DEV_RAYSERRANO_ROLE
Vault database DEV__DV__RAYSERRANO
Landing database DEV__LANDING__RAYSERRANO, read through DBT_LANDING_STORAGE

Your landing database is a clone of LANDING, refreshed on 2026-10-25. It holds four source tables: SUNBELT.CLIENT (43 rows), SUNBELT.POLICY_SALE (14), NORTHFIELD.POLICY (12) and PINECREST.POLICY (12).

3. Where landing data comes from

The vault starts at landing; filling landing is outside it. In this course the teacher stands in for the sources: the teacher creates each new landing table and delivers its rows to LANDING, the production landing database, and your landing database receives them only by being cloned from LANDING again. So a lab never writes to landing: it starts by declaring a landing table as a source and builds the vault from there. When a lab needs data your clone does not yet hold, the teacher refreshes it first.

4. How a lab runs

  1. Make a short lab branch from rayserrano/dig-574-labs, named for the lab.
  2. Read the lab’s sheet: its lesson, the question it moves forward, the starting state and the tasks. The shared delivery documents (profile, design, test plan, implementation guide) hold the full detail; the sheet points to the steps you take.
  3. Before writing code, run the lab’s checks and see which fail; then make them pass. Hints sit behind toggles: try first.
  4. Run the full build in your environment; every test must pass.
  5. Open one pull request from the lab branch into rayserrano/dig-574-labs. The teacher reviews it the way lesson 8 describes.

Workbook: Lab 1-2, declaring Pinecrest Mutual’s source

Lesson Part 1, lesson 2, where data comes from
Linear issue DIG-580, a sub-issue of DIG-574
Branch rayserrano2735/dig-580-lab-1-2-declare-pinecrest-mutuals-source, made from rayserrano/dig-574-labs
Moves forward Question 7 of the ten: where did this record come from, and when did we first know it?

1. The goal

Pinecrest Mutual is a second carrier, invented for the course. Its policy data now sits in your landing database as PINECREST.POLICY: twelve rows over two nights, eight on October 1 and four on October 2, every column text, as Pinecrest sends it. Your lab makes that table a source of the vault: declared to dbt, with the two tests every landed source carries. From here, Labs 1-3 to 1.7 carry its rows into the vault one layer at a time.

2. The starting state

Check Before your work
Your landing database holds PINECREST.POLICY with 12 rows Yes, refreshed from LANDING on 2026-10-25
dbt test –select expect_pinecrest_policy_rows_as_profiled Passes already: the teacher’s test checks that the landed rows match the profile, and the teacher delivered them
dbt ls –select source:pinecrest.policy Returns nothing: the source is not declared. This is your lab’s failing check
The tests nn_pinecrest_policy_loaded_at and uqc_pinecrest_policy_loaded_at_policy_number Do not exist yet

3. Your tasks

Task 1. Declare the source (implementation guide, step 35; design D-39). In dbt/models/staging/_sunbelt__sources.yml, add a source named pinecrest, reading its database from the same environment variable as the others, schema PINECREST, with one table, policy. Copy the northfield source in the same file: that is your exemplar.

Show the hintHide the hint

The northfield source shows the pattern: name, a description, the database from env_var(‘DBT_LANDING_STORAGE’, ‘LANDING’), the schema, then the tables. Give the table a description saying what one row is: one policy, per load.

Task 2. Its two tests (test plan 2.2). On the column LOADED_AT, a not_null test named nn_pinecrest_policy_loaded_at; on the table, dbt_utils.unique_combination_of_columns over LOADED_AT and POLICY_NUMBER, named uqc_pinecrest_policy_loaded_at_policy_number. Both at severity warn, stated explicitly.

Show the hintHide the hint

The sunbelt source’s policy_sale table carries both kinds of test in the shape you need: a tests list on the table for the combination, and a columns list with the not_null under LOADED_AT. Each test takes a name and config: {severity: warn}.

Task 3. Prove and submit (implementation guide, step 36). dbt ls –select source:pinecrest.policy now lists the source; the three Lab 1-2 tests pass; the full build passes, 107 tests in all. Then open one pull request from the branch above into rayserrano/dig-574-labs.

4. What to notice

Lesson 2 said every row the vault keeps carries where it came from and when. Look at what PINECREST.POLICY already gives you for that: LOADED_AT, as text. The record source, PMC, does not exist in the table: Lab 1-3 adds it, in staging. Which of the two does the source itself carry, and which does the vault add?

Check yourself

After this lab, which part of “where did this record come from, and when” does Pinecrest’s data carry by itself, and which part will the vault add?

Show the answerHide the answer

The when arrives with the data: LOADED_AT, as text, which staging will turn into the load timestamp. The where does not: the record source code, PMC, is added by the vault in staging (Lab 1-3), and named in the source system seed (Lab 1-7).