Skip to content

Source YAML Reference

Each source is declared as a single .yml file placed under any directory listed in paths: in smelt.yml. The file must not share its stem with a sibling .csv (that would make it a seed sidecar instead).

File placement and addressing

File on disk (with paths: ["models"]) Address
models/sources/raw/users.yml smelt.sources.raw.users
models/external/api/orders.yml smelt.external.api.orders

The address follows universal path addressing: the scan-root prefix (models/) is stripped, the directory path and stem become the address segments.

A smelt.sources.<path> reference always resolves under the sources namespace; a model whose name happens to collide with a leaf segment does not shadow the source.

Top-level keys

Key Required Default Meaning
description no absent Free-text description of the table, surfaced in LSP hover.
columns yes Column declarations. Required; a source without columns: has no contract to type-check.
name no derived Override the database-side name. Must be a <schema>.<table> literal. When absent, defaults to <target_schema>.<address-path-joined-by-_>.
materialization forbidden Not allowed. Sources are externally managed. Produces a hard error.
timeseries no absent Declares the source's time dimension (event_time_column, partition_column, granularity) — same shape as a model's timeseries: block. See Timeseries reference.
unique_key no absent Identity column(s) — a string or list. Required alongside referential_integrity (a subset of it), and consumed as the once-write/functional-dependency identity a downstream grain: key model's key temporal locality can key off.
mutation_profile no absent (treated as unclocked/worst-case) How this source's underlying data changes over time — append_only, mutable_snapshot, or change_feed, bare-string or structured (see Mutation profile below).
source_lateness no absent Interval (e.g. '2 hours') declaring how far behind "now" this source's data may lag; folded into a downstream model's read window.
referential_integrity no absent Column(s) — a subset of unique_key — guaranteed to have a matching row for every value a consuming model's inner-join enrichment reads by. Narrows an enrichment MERGE's recompute to a point lookup on the changed key(s); re-checked every run, never trusted silently. See Declaring referential integrity.

Column keys

Key Required Default Meaning
name yes Column name as it appears in the database.
type yes smelt DataType — see Supported types.
nullable no true Whether the column may contain NULL. nullable: false is a guarantee that type inference carries downstream. When the column appears on the null-supplying side of an outer join (LEFT JOIN right side, RIGHT JOIN left side, either side of FULL JOIN), inference overrides the declared guarantee and marks the column nullable in the join's output scope.
description no absent Free-text description, surfaced in LSP hover.

Complete example

# models/sources/raw/users.yml
description: Raw user dimension; populated nightly by the CDC pipeline.
columns:
  - name: user_id
    type: INTEGER
    nullable: false
    description: Surrogate key.
  - name: user_name
    type: VARCHAR
  - name: signup_date
    type: DATE

With name: override

# models/sources/raw/users.yml
name: warehouse.users_v2
description: Canonical user table; external name differs from workspace path.
columns:
  - name: user_id
    type: INTEGER
    nullable: false
  - name: user_name
    type: VARCHAR

With name: warehouse.users_v2, smelt emits FROM warehouse.users_v2 in compiled SQL instead of the default <target_schema>.sources_raw_users.

Mutation profile

mutation_profile:
  kind: append_only          # append_only | mutable_snapshot | change_feed
  lateness: '3 days'         # append_only only
  redelivery: at_least_once  # append_only only
  key_recurrence:            # any kind
    key: [event_id]
    window: '3 days'

mutation_profile accepts a bare string (mutation_profile: change_feed) as shorthand for { kind: change_feed }, or the structured block above for kind: plus sub-facts scoped to it:

Field Applies to kind: Meaning
kind any append_only, mutable_snapshot, or change_feed.
lateness append_only How late a row for an already-passed partition may still arrive.
redelivery append_only Redelivery posture — e.g. at_least_once for a feed that may redeliver a row identically.
retractions, ordered, delta_identity change_feed Feed-shape facts describing how the change feed itself is structured.
key_recurrence.key / key_recurrence.window any The declared recurrence bound: every pair of rows sharing the named key(s) lies within window of each other on the event-time axis. This is route 3 (recurrence-bounded) of a downstream grain: key model's key temporal locality — a checked declaration, not a proof: violations fail the consuming run transactionally (KeyedRecurrenceBoundViolated) rather than silently producing a wrong answer. See the deduplication tutorial for a worked example.

Supported types

Type Description
INTEGER 64-bit signed integer
DECIMAL(p,s) Fixed-point decimal, precision p, scale s
DOUBLE 64-bit floating point
BOOLEAN True/false
DATE Calendar date (YYYY-MM-DD)
TIMESTAMP Date and time without time zone
VARCHAR Variable-length string