DE//AGENT
Explore
Tutorial Lesson 5 of 10 · The Warehousing Series community intermediate

Review a dbt model PR before merge

Take a pull request that adds or changes a dbt model and walk the reviewer's pass: read the diff in context, state the model's grain and check it against the unique key test, choose table vs incremental vs view deliberately, and handle late-arriving data in the incremental filter. You finish with findings a reviewer can verify before the model merges.

At a glance

When A PR changes a dbt model's materialisation or incremental filter; A model's unique test does not sit on its declared grain key
Where dbt
Why Grain, materialisation, and late data decide whether a model lies, and this pass checks all three before merge.

Learning objectives

  • State a model's grain in one sentence and match it to the unique test
  • Justify table vs incremental vs view for a given source
  • Add a lookback window so late-arriving rows are not dropped

What you need

  • A pull request that adds or changes a dbt model
  • The model's schema.yml with its declared grain
  • [object Object]

Steps

  1. Read the diff and the file context. (from agent-sql-reviewer )
  2. Establish the grain of every result set. (from agent-sql-reviewer )
  3. State a model's grain and match it to its unique key test. (from skill-dbt-model-review )
  4. Choose table vs incremental vs view deliberately. (from skill-dbt-model-review )
  5. Handle late data in an incremental model. (from skill-dbt-model-review )

Check yourself

  • The review states the model's grain in one sentence and the unique test sits on that key.
  • An incremental model carries a lookback window such as >= max(updated_at) - interval '3 days'.

Worked example

Grain first - the unique test on the declared grain key — from skill-dbt-model-review

# One row = one ___ ; the unique test goes on that key
models:
  - name: <model>
    columns:
      - name: <grain key>
        tests:
          - unique

Materialisation picker - view vs table vs incremental — from skill-dbt-model-review

view        - cheap, and the model is small or rarely queried.
table       - the source is huge and consumers need speed.
incremental - the source grows monotonically and you can define the watermark.

Incremental filter with a lookback window, guarded by is_incremental() — from skill-dbt-model-review

-- late-arriving rows older than the watermark are silently dropped
{% if is_incremental() %}
  where updated_at >= max(updated_at) - interval '3 days'
{% endif %}

Sourced from

Security scan

Last sweep 2026-10-24: 0 finding(s), 0 marked as examples.

Common gotchas

  • Late-arriving rows older than the watermark are silently dropped — add a lookback window.
  • is_incremental() must guard the filter or every full run is a full reload.
  • Deletes never arrive — decide explicitly: soft-delete, or periodic full-refresh.

Production considerations

  • Add a lookback window (e.g. >= max(updated_at) - interval '3 days') to every incremental filter.
  • Decide soft-delete vs periodic full-refresh explicitly; deletes never arrive on their own.

Diagram

dbt model review
   |
   |- read diff + context --> establish grain per result set
   |
   |- grain statement --> unique test on that key
   |
   |- materialisation picker --> view / table / incremental
   |
   |- incremental --> lookback window --> guard is_incremental()

Registry stats

Verification community · Oct 21, 2026
Completeness 81
Trust multiplier ×1.25
Composite 34.15 · adequate
Freshness 3 days since last source check
Difficulty intermediate
Version 0.1.0
License CC-BY-4.0
Security flags none