Skip to content
Reliable Data Engineering
Practice problem medium scd2data-modelingmerge
Solve it in the browser (Python editor)

Apply a Daily Snapshot to an SCD Type 2 Dimension

Difficulty: Medium · Topics: scd2, data-modeling, merge · Asked at: Databricks, Snowflake, Capgemini, any DWH team

Problem

dim is a list of rows {"key", "attrs" (dict), "valid_from", "valid_to", "is_current"} with valid_to = "9999-12-31" for current rows. snapshot maps key → attrs for date as_of (ISO string). Return the new dimension list (sorted by key, valid_from) after applying SCD2:

Starter code

def apply_snapshot(dim: list[dict], snapshot: dict, as_of: str) -> list[dict]:
    pass

Hints

Hint 1

Index current rows by key. Copy rows before changing them.

Solution

OPEN = "9999-12-31"

def apply_snapshot(dim: list[dict], snapshot: dict, as_of: str) -> list[dict]:
    out = [dict(r) for r in dim]
    current = {r["key"]: r for r in out if r["is_current"]}
    for key, row in current.items():
        if key not in snapshot:
            row.update(valid_to=as_of, is_current=False)
        elif snapshot[key] != row["attrs"]:
            row.update(valid_to=as_of, is_current=False)
            out.append({"key": key, "attrs": dict(snapshot[key]), "valid_from": as_of, "valid_to": OPEN, "is_current": True})
    for key, attrs in snapshot.items():
        if key not in current:
            out.append({"key": key, "attrs": dict(attrs), "valid_from": as_of, "valid_to": OPEN, "is_current": True})
    return sorted(out, key=lambda r: (r["key"], r["valid_from"]))

Tests

Your solution should pass these:

dim = [
    {"key": 1, "attrs": {"tier": "bronze"}, "valid_from": "2026-01-01", "valid_to": "9999-12-31", "is_current": True},
    {"key": 2, "attrs": {"tier": "gold"},   "valid_from": "2026-01-01", "valid_to": "9999-12-31", "is_current": True},
    {"key": 3, "attrs": {"tier": "silver"}, "valid_from": "2026-01-01", "valid_to": "9999-12-31", "is_current": True},
]
snap = {1: {"tier": "silver"}, 2: {"tier": "gold"}, 4: {"tier": "bronze"}}
new = apply_snapshot(dim, snap, "2026-02-01")
assert [(r["key"], r["attrs"]["tier"], r["valid_from"], r["valid_to"], r["is_current"]) for r in new] == [
    (1, "bronze", "2026-01-01", "2026-02-01", False),
    (1, "silver", "2026-02-01", "9999-12-31", True),
    (2, "gold",   "2026-01-01", "9999-12-31", True),
    (3, "silver", "2026-01-01", "2026-02-01", False),
    (4, "bronze", "2026-02-01", "9999-12-31", True),
]
assert dim[0]["is_current"] is True     # input not mutated

Explanation

O(n + m). This is what MERGE INTO dim USING (staged changes) does in Delta/Snowflake, or dbt snapshot: the classic trick is a staged source that contains each changed key twice (once to close the old row, once to insert the new one) so a single MERGE handles both. Idempotency question: running the same snapshot twice must not create duplicate versions. Here the second run sees unchanged attrs and does nothing.