Export the semantic layer
Your gold contracts already carry metric definitions — measures, dimensions, entities — as governed metadata. The semantic-layer export is what turns those definitions into the file formats a BI tool actually reads, so a metric declared once in a contract shows up consistently in Power BI, Tableau, or a headless BI layer, rather than being re-authored per tool.
There are two export paths: the contract-centric kiri contract export semantic-layer, and the gold-oriented kiri semantic group. They share
the same underlying exporters.
Four target formats
| Target | What it emits | Where it goes |
|---|---|---|
metricflow | MetricFlow YAML — dbt-core’s official semantic-layer engine | one file per semantic model, dropped into models/semantic/ |
dbt-semantic | dbt Semantic Layer YAML (byte-identical wire format to MetricFlow; different convention for where files live) | models/semantic/<name>.yml in a dbt project |
cube | Cube YAML — the non-dbt, headless-BI option | one <contract>.yml per gold contract |
databricks-metric-views | Unity Catalog Metric View YAML — the warehouse-native semantic layer | governed metrics living in Unity Catalog itself |
metricflow and dbt-semantic are the same renderer: MetricFlow is
dbt-core’s semantic-layer engine, and the dbt Semantic Layer is built on
it, so the emitted YAML is identical — what differs is the directory
convention the target expects. cube is a genuinely different wire format
(top-level cubes:, SQL-fragment joins, explicit dimension and measure
types). databricks-metric-views keeps the governed metric in Unity
Catalog instead of in a per-tool file.
What maps to what
The export reads your gold contracts and projects each into a vendor-neutral semantic model — entities, dimensions, and measures — then renders that into the target’s shape:
- Measures. A contract measure with its aggregation (
sum,count,count_distinct,avg,min,max) becomes a MetricFlow measure or a Cube measure with the matchingtype:. Metrics that draw from a model’s measures are co-located in the same file so a reader sees the whole unit. - Dimensions. Contract dimensions become the target’s dimension
entries. Cube additionally carries an explicit dimension
type:(string/number/time/boolean) for its runtime type-checking. - Entities and relationships. Foreign-key relationships map to
MetricFlow entities, to Cube’s
joinsarray withbelongs_to/has_manyrelationships and a primary-key flag, and — for Unity Catalog Metric Views — to foreign-key comments rather than ajoins:block, which you turn into real joins (a UC join needs both source andon/using, and the joined dimension’s physical source isn’t in the measure model).
Only qualifying gold contracts export; if a filter leaves nothing, the CLI tells you it skipped rather than writing zero files silently.
Exporting via kiri contract export
The contract-centric command renders every gold contract, or one:
# Explicit target + output directory
kiri contract export semantic-layer --target metricflow --output models/semantic/
# Rely on the semantic_layer: block in kiri.yml
kiri contract export semantic-layer
# Filter to a single contract
kiri contract export semantic-layer --contract orders
You can either pass --target and --output explicitly, or configure a
semantic_layer: block in kiri.yml and run the command with no flags.
Mixed mode — one flag set, the other from config — is rejected on purpose,
so you always see exactly what you’re emitting and where.
Exporting and applying via kiri semantic
The gold-oriented kiri semantic group adds an emit / apply / verify
lifecycle, and is where the Unity Catalog Metric Views path lives its
fullest life.
# Emit semantic-layer YAML to stdout (pipe into downstream deploy tooling)
kiri semantic sync --backend metricflow
# Or write it to a file
kiri semantic sync --backend cube -o cube_models.yml
kiri semantic sync supports cube, metricflow, and
databricks-metric-views. Output defaults to stdout so you can pipe it
into dbt sl, a Cube deploy, or your own tooling; -o writes a file.
For Unity Catalog Metric Views, sync is only the first step — you can
also apply and verify:
# Dry-run the CREATE OR REPLACE VIEW … WITH METRICS DDL
kiri semantic apply --backend databricks-metric-views
# Diff live Metric Views against what the contracts declare
kiri semantic verify --backend databricks-metric-views
kiri semantic apply is dry-run by default. Executing the DDL against a
live target requires --no-dry-run, KIRIMANA_SEMANTIC_VIEWS_LIVE=1, and
a Unity Catalog target; without all three it downgrades to dry-run so you
can’t accidentally mutate production. kiri semantic verify diffs the live
Metric Views against the contracts and controls its exit code via
--fail-on missing|stale|all, which makes it a natural CI gate: regenerate
the semantic layer, apply it, and fail the build if what’s live drifts from
what the contracts declare.
Picking a target
Reach for metricflow or dbt-semantic if your BI tools already speak
the dbt Semantic Layer — the metric definition lives next to your dbt
models and your existing dbt tooling picks it up. Reach for cube for
headless or embedded-analytics use cases. Reach for
databricks-metric-views when you want the governed metric to live inside
Unity Catalog itself, so every consumer of the warehouse — BI tool, notebook,
or query — reads the same definition without a per-tool re-authoring step.