sources/ in your project directory.
Table sources
Point at an existing table or view in your warehouse:__source("raw_events").
Expression sources
Define source data inline as a SQL expression. No external tables or setup scripts needed:Source audits
Sources support the same audit system as models. Audits attached to sources run before any dependent model is built:error severity fails, all downstream models that depend on that source are blocked.
Type enforcement
Type enforcement is implicit for sources, the same as for models. If any column declares atype, SQLBuild automatically casts that column and uses declared types for schema-change detection:
id has a type declared, so only id is cast. Columns without a type are passed through unchanged.
For expression sources, SQLBuild probes the expression’s output columns and builds a projection that casts typed columns while preserving the rest. For table sources, it uses warehouse metadata to validate that declared column names exist and applies casts accordingly.
You can explicitly set type_enforcement: false on a source to disable casting even when column types are declared.
Managed sources (loaders)
Sources can be loaded by Python functions instead of pointing at existing tables or inline expressions. Setmanaged: true to bind a source to the @loader function of the same name, and SQLBuild will call it to populate the source table:
table, append, delete_insert, merge), cursor-based loading, and concurrent execution.
See Loaders for the full guide on writing loader functions, write strategies, the loader context API, and auto-load behavior during builds.
Source freshness
Source freshness lets SQLBuild observe whether a source’s data has changed between runs. This feeds into planning and change detection: models downstream of unchanged sources are skipped automatically. Configure freshness per source with afreshness: block:
Strategies
| Strategy | Description | Required fields |
|---|---|---|
adapter | Uses warehouse metadata (e.g. Snowflake LAST_ALTERED). No query against the source table. | None |
column | Reads MAX(column) from the source table. | column, type |
sql | Runs a custom query that returns a single scalar value. | query, type |
adapter
type, column, or query.
column
MAX(column) from the source table. The column must be a plain column name (no expressions; use sql strategy for those). Requires type.
sql
type. Does not support column.
Type
Thetype field declares the value kind for comparison:
| Type | Description |
|---|---|
timestamp | Datetime value. Supports lag_tolerance. |
integer | Integer value. Change detected by exact comparison. |
string | String value. Change detected by exact comparison. |
Lag tolerance
lag_tolerance is optional and only valid with type: timestamp. It declares how much the observed timestamp can drift from the previous observation before being treated as a change:
15m (minutes), 2h (hours), 1d (days). If the current observation is within the tolerance of the previous one, the source is treated as unchanged.
Auto-observation
Sources without an explicitfreshness: block are auto-observed using the adapter strategy if:
- The source has a physical table (not an expression source)
- The source is not managed
- The adapter supports table freshness metadata
sqb freshness to observe source freshness on demand without triggering a build. See Planning and Change Detection for how freshness feeds into change-aware builds.
Freshness config reference
| Field | Description |
|---|---|
strategy | Observation strategy: adapter, column, or sql |
type | Value kind: timestamp, integer, or string |
column | Column name for column strategy |
query | SQL query for sql strategy |
lag_tolerance | Duration tolerance for timestamp comparisons (e.g. 15m, 2h, 1d). Only valid with type: timestamp. |
Config reference
| Field | Description |
|---|---|
name | Source name, used in __source("name") references |
database | Target database (optional) |
schema | Target schema (optional) |
table | Target table name (defaults to name if omitted) |
expression | Inline SQL expression (alternative to table reference) |
managed | Set to true to bind the source to the @loader function of the same name (see Loaders) |
write_strategy | How the loader writes data: table, append, delete_insert, or merge (requires managed: true) |
cursor_column | Column for incremental cursor tracking (required for delete_insert and merge) |
unique_key | Merge key column(s) (required for merge) |
freshness | Source freshness observation config (see Source freshness) |
description | Human-readable description |
type_enforcement | Override implicit type enforcement (true/false). Defaults to true when any column declares a type. |
contract | enforced or none. When enforced, downstream models validate configured column references against source columns. |
columns | Column declarations with optional types and audits |
audits | Source-level audits |

