dbt-fabric
The dbt adapter that connects dbt Core to Microsoft Fabric Synapse Data Warehouse for SQL-based transformations.
Repository Health
Technical Analysis
dbt-fabric is the official Microsoft-maintained dbt adapter for Microsoft Fabric Synapse Data Warehouse. It plugs into dbt Core’s adapter framework so teams can write SQL (and Jinja) models, run them as views, tables, or incremental loads directly inside a Fabric Warehouse, and get dbt’s testing, documentation, and dependency-graph features on top of Fabric’s Azure-native compute.
Beyond standard materializations, the adapter ships Fabric-specific engineering: a table-refresh planner that decides whether a full-refresh can reuse the existing physical table (avoiding a drop/recreate when schema and constraints haven’t changed), constraint diffing for primary/foreign/unique keys, and a Microsoft Purview sync module that pushes dbt model metadata (descriptions, lineage, column docs) into Purview’s Atlas-based catalog after a run.
Authentication is handled through mssql-python (Microsoft’s own ODBC-based driver) with support for Azure AD service principals, managed identity, and workload identity federation via a dedicated token provider, making it usable both from local development and from Azure-hosted CI/CD runners without embedding credentials.
What You Get
- Full support for dbt’s standard materializations (view, table, incremental, seed) targeting Fabric Warehouse
- A table-refresh planner that avoids unnecessary drop/recreate cycles when a full-refresh’s schema and physical layout haven’t changed
- Constraint management (primary key, foreign key, unique, not null) with diffing against the existing table before altering it
- Microsoft Purview integration (
PurviewSync/PurviewClient) that syncs model descriptions, column docs, and lineage to Purview’s Atlas catalog after a run - Multiple authentication modes — Azure AD service principal, managed identity, and workload identity federation — via a dedicated
FabricTokenProvider - Bundled macro library covering dbt-utils, dbt-date, dbt-expectations, and dbt-external-tables compatibility shims for Fabric
Common Use Cases
- Running an existing dbt Core project’s SQL transformations against a Microsoft Fabric Warehouse instead of Synapse Dedicated SQL Pool or another warehouse
- Migrating a dbt project from Snowflake/BigQuery/Databricks onto Fabric as part of a Microsoft Fabric platform adoption
- Automatically publishing dbt model lineage and documentation into Microsoft Purview for enterprise data governance
- Running large (500+ model) dbt projects on Fabric while tuning thread count and catalog-cache flags to avoid catalog-lock contention on concurrent runs
- Authenticating dbt runs from Azure DevOps/GitHub Actions CI using managed identity or workload identity instead of static credentials
Under The Hood
Architecture
The adapter follows dbt-core’s standard adapter-plugin contract: dbt/adapters/fabric/__init__.py registers an AdapterPlugin wiring together FabricAdapter (extends BaseFabricAdapter/SQLAdapter), FabricCredentials, and a macro include path. FabricConnectionManager (built on BaseFabricConnectionManager) owns the ODBC connection lifecycle and SQL exception translation into dbt’s own error types, while FabricAdapter layers Fabric-specific behavior on top — most notably get_table_refresh_plan, which delegates to table_refresh.py’s build_refresh_plan to decide between an in-place reload and a full replace, and constraint diffing via desired_constraint/diff_constraints. A separate concern, Purview sync (purview_sync.py, purview_client.py, purview_api_client.py), hooks into dbt’s on-run-end results to push metadata to an external service, keeping governance sync decoupled from the core SQL execution path. What would break if the core abstraction changed: BaseFabricAdapter/BaseFabricConnectionManager centralize behavior shared with dbt-core’s SQL adapter base classes, so a dbt-core adapter-interface change is the single highest-blast-radius risk.
Tech Stack
Written in Python 3.11-3.13, built with hatchling and versioned from dbt/adapters/fabric/__version__.py. Runtime dependencies are mssql-python (Microsoft’s ODBC driver replacing the older pyodbc), azure-identity/azure-core for AD/managed-identity auth, requests for the Purview REST client, and dbt-common/dbt-core/dbt-adapters pinned to dbt 1.11+. Dev tooling uses uv for dependency management, ruff for linting/formatting (line-length 99, py312 target), mypy for type checking, and pytest with pytest-xdist/flaky/freezegun for unit and functional test runs against a live or Dockerized Fabric endpoint (docker-compose.yml). CI runs unit tests and Azure integration tests as separate GitHub Actions workflows, plus a Docker image publish workflow.
Code Quality
The repo has an extensive test suite (55 test files split across tests/unit and tests/functional/adapter), with unit tests directly exercising pure functions like build_refresh_plan and diff_constraints via parametrized pytest cases, and functional tests inheriting dbt-core’s adapter test-adapter contract suite. Code is fully type-hinted (Python 3.11+ union syntax), uses dataclasses for structured types (FabricTableColumn, FabricTableConstraint), and raises dbt’s own typed exceptions (DbtDatabaseError, DbtRuntimeError) rather than swallowing errors. ruff and mypy run in pre-commit and CI, with ignore_missing_imports scoped narrowly to untyped third-party stubs rather than disabled wholesale.
What Makes It Unique Most dbt adapters implement materializations and stop there; dbt-fabric adds two pieces of engineering rarely seen in adapter plugins: a refresh-plan optimizer that inspects schema and physical-layout equivalence to skip a full table rebuild on unchanged full-refreshes (reducing Fabric’s DDL catalog-lock pressure on large concurrent runs), and a first-party Microsoft Purview sync path that turns dbt’s own model metadata into governance catalog entries automatically after every run — collapsing what’s normally a separate lineage-ingestion pipeline into the adapter itself.