Skip to content

Sources & schema — name your columns

The question for this lesson: before Clinker can transform your data, it has to read it and know what each column is: text, a number, a date. Where does that come from?

  • Declare a schema on a source: name and type each column.
  • Choose the right type for a column, and know which types exist.
  • Decide what happens to columns that aren’t in your schema.

This is the most important thing to know about sources: you declare the columns and their types; Clinker does not infer them. A CSV header only names columns; it never sets types.

A source’s schema: is a list of { name, type } entries:

- type: source
name: customers
config:
type: csv
path: ./data/customers.csv
options: { has_header: true }
schema:
- { name: customer_id, type: string }
- { name: status, type: string }
- { name: amount, type: int }
- { name: signed_up, type: date }

The types you can use in an inline schema:

TypeFor
stringtext
intwhole numbers
floatdecimal numbers
booltrue / false
date, date_timea date, or a date + time
array, mapa list, or a set of key/values
🌱 New here? — picking a type

Match the type to how you’ll use the column, not just what it looks like. A zip code looks like a number but you never do math on it, so make it string and the leading zero (“01970”) survives. A price you’ll compare or total should be int or float.

“Declared, not inferred” cuts both ways: the type you write has to be one Clinker knows. A made-up type like dollars is not silently accepted or guessed. It’s rejected before any data is read. If you change amount’s type to dollars and validate:

schema:
- { name: customer_id, type: string }
- { name: amount, type: dollars } # not a real type

clinker run pipeline.yaml --dry-run stops with exit 1 and tells you exactly which names are valid:

pipeline error in pipeline.yaml: config error: YAML parse error:
unknown variant `dollars`, expected one of null, bool, int, float,
string, date, date_time, array, map, numeric, any, nullable

That list (null, bool, int, float, string, date, date_time, array, map, numeric, any, nullable) is the full set of names the inline schema accepts.

// quick check

A column holds US zip codes like 01970. What type should it be?

What about columns in the file that you didn’t list in the schema? The on_unmapped setting decides:

  • auto_widen (default): keep them, as text.
  • reject: fail if the file has a column you didn’t declare.
  • drop: silently ignore them.
config:
type: csv
path: ./data/customers.csv
options: { has_header: true }
on_unmapped: reject # be strict: an unexpected column is an error
schema:
- { name: status, type: string }

Predict, then run: this source declares amount as int. Trace what the output type of amount is, versus customer_id (declared string).

pipeline.yaml // editable

A --dry-run validates the config and the declared schema without reading any data, so the summary line reports the shape of the pipeline (here, one source, one output, and no transforms) and exits cleanly. It does not print a column-by-column type table; the place the types live is the schema: you wrote.