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?
What you’ll be able to do
Section titled “What you’ll be able to do”- 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.
Clinker does not guess types
Section titled “Clinker does not guess types”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.
Declaring a schema
Section titled “Declaring a schema”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:
| Type | For |
|---|---|
string | text |
int | whole numbers |
float | decimal numbers |
bool | true / false |
date, date_time | a date, or a date + time |
array, map | a 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.
Only the listed types are real
Section titled “Only the listed types are real”“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 typeclinker 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, nullableThat 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?
Pick the type by how you use the column. Zip codes aren't arithmetic, and int would drop the leading zero. string keeps 01970 intact.
Columns that don’t fit: on_unmapped
Section titled “Columns that don’t fit: on_unmapped”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 }Try it
Section titled “Try it”Predict, then run: this source declares amount as int. Trace what the output type of
amount is, versus customer_id (declared string).
> output appears here — predict, then run
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.