Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.sqlbuild.com/llms.txt

Use this file to discover all available pages before exploring further.

Detect SQL changes, automatically trigger rebuilds, and control backfill windows - without fragile configs.

How it works

  1. Define your models as SQL files with MODEL() headers and optional schema YAML
  2. Compile to resolve references, validate SQL (with SQLGlot), and expand Python macros
  3. Plan what needs to change based on fingerprints, schema diffs, and backfill policies
  4. Build by executing the plan: materializing models, validating data before promotion, and ensuring bad data never reaches production
  5. Iterate with first-class support for chained unit tests, zero-copy cloning, and deferred builds - fast feedback without rebuilding the world

Why SQLBuild?

SQL unit tests that scale

  • Chain across models: Mock your sources, assert on the model you care about, and SQLBuild automatically resolves every intermediate model using its real SQL. One test file can be a full integration test across your entire pipeline.
  • Macro-powered mocks: Because unit tests are written in SQL, they support macro calls, so you can write reusable mock generators and fixture builders instead of copy-pasting mock inputs across test files.
-- Mock two sources, assert on the final mart.
-- stg_orders and stg_payments resolve automatically from their real SQL.
TEST();

WITH
__source__raw_orders AS (
  @mock_orders()
),
__source__raw_payments AS (
  SELECT 1 AS payment_id, 1 AS order_id, 1500 AS amount_cents, 'credit_card' AS method
),
__expected__fact_orders AS (
  SELECT 1 AS order_id, 100 AS customer_id, 1500 AS total_cents,
         'credit_card' AS payment_method
)
SELECT 1

Audits that block bad data

  • Full table builds: SQLBuild materializes into a staging table and runs error-severity audits before promotion. If any fail, the swap is blocked and the production table is untouched.
  • Incremental models: Delta-phase audits validate each batch before DML is applied. Bad data is caught before it reaches the target.

Python macros, not Jinja

  • Real Python functions: Testable, debuggable, and composable with standard tooling. No templating language, no string interpolation surprises.
# macros/grant_target.py
def grant_target(target):
    return f"GRANT SELECT ON {target} TO analyst_role"

Change-aware incremental rebuilds

  • Query-change detection: Fingerprint-based tracking detects when model SQL has actually changed and triggers bounded or full rebuilds automatically.
  • Backfill cascade: Upstream query or schema changes propagate rebuild signals downstream through the DAG, with per-model control over rebuild windows.
  • Schema diffs in the plan: The plan shows column additions, removals, and type changes before anything executes, with configurable policies to block or adapt.
  • Controlled rebuild windows: query_change_backfill and schema_change_backfill policies let you choose between full rebuild and bounded replay (e.g. bounded(14d)).

Incremental processing

  • Cursor-based replay: SQLBuild tracks position using a timestamp or integer column and automatically detects where to resume. If a model fails for several runs, the next successful build replays from where it left off with no manual backfilling.
  • Microbatch mode: Split large replay windows into configurable batches, each with its own audit cycle. Or process the full range in one pass, the choice is per-model.

Multi-environment workflows

  • Environment diffs: Compare schemas and row-level data between environments with sqb diff --from prod --to dev.
SQLBuild diff output showing schema comparison, row-level differences, and changed column values between prod and dev environments
  • Zero-copy cloning: Branch environments instantly with sqb clone without duplicating data.
  • Deferred references: Compile and plan against a production environment with --defer-to while building in dev.
  • No manifest required: Clone, diff, and defer work directly against live environments. No manifest.json generation, no artifact management, no stale state.

Extensibility

  • Custom materializations: Write materialization logic in Python with full framework integration - including audit hooks, schema change signals, and query change detection.
def materialize(ctx: MaterializationContext) -> MaterializationResult:
    stale = find_untracked_partitions(ctx)

    for partition in stale:
        ctx.adapter.create_table_as(ctx.connection, target=staging, sql=partition_sql)
        ctx.run_audits(staging)  # same audit guarantees as built-in types
        ctx.execute_sql(f"INSERT INTO {ctx.target} SELECT * FROM {staging}")

    return MaterializationResult(relation=ctx.target)
  • Path-between selectors: --select fact_orders~daily_activity_rollup selects every model on the shortest path between two nodes, with optional upstream/downstream expansion.

Quickstart

Get a project running locally in minutes.

CLI Reference

Full reference for every SQLBuild command.

Concepts

Understand models, incremental strategies, audits, and selectors.

Waffle Shop Example

Walk through a complete example project.