Warehouse snapshots
A warehouse snapshot is a read-only, point-in-time view of a Fabric Data Warehouse. Snapshots let downstream consumers (reports, analysts, other pipelines) query a stable version of the data while your dbt run is modifying the warehouse. They can be "rolled forward" on demand and are retained for up to 30 days.
The dbt-fabric-samdebruyn adapter ships a macro that lets you create or update a warehouse snapshot from anywhere in your dbt project — giving you full control over when and how often snapshots are taken.
Why this adapter?
Microsoft's upstream dbt-fabric adapter also supports warehouse snapshots, but it bakes the feature into the adapter internals by hijacking Python runtime components. Their implementation does not respect the proper dbt lifecycle — it bypasses dbt's hook system entirely and instead injects snapshot logic into the running Python code. You get a single snapshot per run, triggered automatically at either the start or end, with no further control.
This adapter takes a different approach: it exposes a macro that you call explicitly, putting you in charge.
| dbt-fabric (Microsoft) | dbt-fabric-samdebruyn | |
|---|---|---|
| How | Built into the adapter internals | A macro you call explicitly |
| When | Automatically at the start or end of a run (configured via a profile setting) | Wherever you decide: on-run-start, on-run-end, post-hook, or any other Jinja context |
| Flexibility | Single snapshot per run, limited control | Multiple snapshots, dynamic names, custom timing |
This means you can take snapshots at multiple points during a run, use dynamic names (e.g. including the date), scope them to specific models, or skip them entirely on certain invocations — all by writing standard dbt configuration.
The macro
{{ create_or_update_fabric_warehouse_snapshot(snapshot_name, description) }}
| Parameter | Type | Required | Description |
|---|---|---|---|
snapshot_name |
string | yes | Display name of the snapshot in Fabric. Must be unique within the workspace. |
description |
string | no | Human-readable description shown in the Fabric portal. |
Behavior:
- If a snapshot with the given name does not exist yet, a new one is created at the current point in time.
- If a snapshot with the given name already exists, its timestamp is rolled forward to the current point in time.
This means you can safely call the macro multiple times with the same name — it will always update the snapshot to the latest state.
When to use it
The macro can be called in any place where dbt allows you to run SQL or call macros:
on-run-start / on-run-end hooks
These hooks run once at the very beginning or end of a dbt invocation (dbt run, dbt build, dbt test, dbt seed, …). This is the most common way to use warehouse snapshots.
Take a snapshot after all models have been built:
on-run-end:
- "{{ create_or_update_fabric_warehouse_snapshot('daily_snapshot', 'Snapshot taken after dbt run') }}"
Take a snapshot both before and after the run. This gives you a "before" and "after" view of the warehouse:
on-run-start:
- "{{ create_or_update_fabric_warehouse_snapshot('pre_run_snapshot', 'State before dbt run') }}"
on-run-end:
- "{{ create_or_update_fabric_warehouse_snapshot('post_run_snapshot', 'State after dbt run') }}"
Use the same snapshot name in both hooks. The on-run-start hook creates it, and the on-run-end hook rolls it forward to the post-run state:
on-run-start:
- "{{ create_or_update_fabric_warehouse_snapshot('latest_snapshot') }}"
on-run-end:
- "{{ create_or_update_fabric_warehouse_snapshot('latest_snapshot') }}"
post-hook on a model
A post-hook runs after a specific model is built. Use this if you want a snapshot taken at the exact point when a particular model has finished.
{{ config(
post_hook="{{ create_or_update_fabric_warehouse_snapshot('after_revenue', 'Taken after revenue model') }}"
) }}
select ...
Or apply it to an entire folder in dbt_project.yml:
models:
my_project:
marts:
+post-hook:
- "{{ create_or_update_fabric_warehouse_snapshot('marts_snapshot') }}"
Use on-run-end for most cases
post-hook runs after each model it applies to. If you attach it to a folder with 20 models, the snapshot will be updated 20 times. For a single snapshot per run, prefer on-run-end.
Dynamic snapshot names
Since the macro is called from Jinja, you can use any Jinja expression for the snapshot name. For example, include the current date:
on-run-end:
- "{{ create_or_update_fabric_warehouse_snapshot('snapshot_' ~ modules.datetime.datetime.now().strftime('%Y%m%d')) }}"
Or use an environment variable:
on-run-end:
- "{{ create_or_update_fabric_warehouse_snapshot(env_var('SNAPSHOT_NAME', 'default_snapshot')) }}"
Prerequisites
Warehouse snapshots use the Fabric REST API, so the same requirements as for workspace auto-discovery apply:
workspaceorworkspace_idmust be configured in your profile- Your authentication identity must have admin, member, or contributor permissions on the workspace
No additional configuration options are needed beyond the standard connection settings.
How it works
- The macro calls the adapter's
create_or_update_warehouse_snapshotmethod. - The adapter uses the Fabric REST API to either create a new snapshot or update an existing one.
- Snapshot creation is an asynchronous operation — the adapter tracks the operation and waits up to 30 minutes for it to complete if needed (e.g. when the same snapshot is updated again later in the same run).
- The snapshot is scoped to the Data Warehouse configured in your
databaseoption.
Limitations
- Snapshot names must be unique within the workspace — they cannot share a name with a warehouse or SQL analytics endpoint.