OSI Field Mapping: every semantic layer, one spec
A field-by-field reference of how MetricFlow, Cube, LookML, AtScale, Snowflake Semantic Views, GoodData, Power BI and Databricks Metric Views translate onto the Open Semantic Interchange schema — the vendor-neutral wire format for the modern semantic layer.
1 · Dataset Layer (tables & sources)
How each product names the physical table that backs a semantic object, and how OSI unifies those names under dataset.name + dataset.source.
dataset.namesemantic_model.namecubes[].nameview: view_nameTABLES (alias AS …)dataset.idtable 'Name'CREATE METRIC VIEW namedataset.sourceref() or source YAMLcubes[].sql_tabledataset.sourcesql_table_name / derived_tableTABLES (alias AS db.schema.table)dataset mappingpartition.source (M / SQL)source: catalog.schema.tabledataset.primary_keyentities[] with type: primarydimensions[] with primary_key: truelevel_attributes[].key_columnsdimension: + primary_key: yesPRIMARY KEY (col)attribute labelscolumn.isKey: truedataset.descriptionsemantic_model.descriptionCOMMENT = '…'dataset.descriptiontable.descriptionCOMMENT '…'The name of a semantic object varies wildly across tools — cube, view, semantic_model, a raw SQL alias — but every product ultimately points at one physical table. OSI collapses that into two fields: dataset.name for the logical identifier your metrics reference, and dataset.source for the exact table binding downstream consumers hit.
2 · Dimensions Layer (fields & attributes)
Field-level metadata: names, expressions, labels, descriptions, and the two pieces most products lack — a time flag and an AI-context slot.
fields[].namedimensions[].namedimensions[].namedimension.unique_namedimension: field_nameDIMENSIONS (table.dim AS …)attribute.id + label.idcolumn.namedimensions[].namefields[].expression.dialects[]dimensions[].expr (single dialect)dimensions[].sql (single dialect)level_attribute.columndimension: { sql: ${TABLE}.col }DIMENSIONS (… AS sql_expr)label.source_columncolumn.sourceColumn or DAX calc columndimensions[].expr (SQL)fields[].dimension.is_timetype: time + time_granularitytype: timetype: TIMEdimension_group + timeframesattribute onlydataType: dateTime + mark-as-date-tablefields[].labeldimensions[].labeldimensions[].titlelevel_attribute.labeldimension.labellabel.titledimensions[].labelfields[].descriptiondimensions[].descriptiondimensions[].descriptionlevel_attribute.descriptiondimension.descriptionCOMMENT = '…'attribute.descriptioncolumn.descriptiondimensions[].commentfields[].ai_contextWITH SYNONYMS = ('…')column.synonyms (Q&A)fields[].custom_extensionsdimensions[].type_paramsdimensions[].metadimension.type / formattags / group_labelWITH TAG (…)label.value_typeannotations[]OSI's fields[].expression.dialects[] is the one place multi-dialect SQL can live natively — MetricFlow, Cube and LookML each assume a single dialect. And fields[].dimension.is_time is the only cross-product flag any consumer can rely on for time dimensions: no more sniffing LookML's dimension_group, MetricFlow's type: time, and Snowflake's raw SQL to guess the same thing three different ways.
3 · Metrics Layer (measures & aggregations)
How each product describes aggregations, filters, and derived metrics — and how OSI pulls the aggregation out of the SQL string into a first-class field.
metrics[].namemeasures[].namemeasures[].namemetric.unique_namemeasure: field_nameMETRICS (table.metric AS …)metric.idmeasure.namemeasures[].namemetrics[].aggregationmeasures[].agg (sum, count_distinct…)measures[].type (sum, avg…)metric.aggregation_typemeasure: { type: sum }SUM(...))SUM(...))SUM(...))metrics[].expressionmeasures[].exprmeasures[].sqlmetric.expressionmeasure: { sql: ${TABLE}.col }METRICS (… AS sql_expr)metric.maqlmeasure.expression (DAX)measures[].expr (SQL)metrics[].descriptionmeasures[].descriptionmeasures[].descriptionmetric.descriptionmeasure.descriptionCOMMENT = '…'metric.descriptionmeasure.descriptionmeasures[].commentmetrics[].filtermeasures[].filtermeasures[].filters[]metric.filtermeasure: { filters: [...] }CALCULATE(..., filter)WHERE in measure exprmetrics[].labelmeasures[].labelmeasures[].titlemetric.labelmeasure.labelmetric.titlemeasures[].labelmetrics: block (ratio, derived)measures[].sql referencing other measurestype: number, sql: ${m1}/${m2}metric.maql referencing other metricsMEASURE(name) reference in metric viewmetrics[].ai_contextWITH SYNONYMS = ('…')measure.synonyms (Q&A)Snowflake Semantic Views and GoodData embed the aggregation inside the expression string (AS SUM(...), SELECT SUM({fact})). OSI moves it out to metrics[].aggregation so agents and BI tools can reason about the operation without parsing SQL. Derived metrics that reference other metrics are preserved verbatim through metrics[].expression.
4 · Relationships Layer (joins)
Where joins are declared and where they must be inferred. OSI hoists them into a first-class relationships[] block.
relationships[].nameentity.namejoins[].nameRELATIONSHIPS (name AS …)reference declarationrelationship.namejoins[].namefrom_dataset / to_datasetentity.type: foreignjoins[].nametable_a (col) REFERENCES table_bfromTable / toTablejoins[].sourcerelationships[].foreign_keyentities[].exprjoins[].sqljoin: { sql_on: ${a}.fk = ${b}.pk }fromColumn / toColumnjoins[].on (SQL predicate)relationships[].cardinalityjoins[].relationshiprelationship: many_to_onecardinality: manyToOneThis is the most inconsistent layer across the six products. MetricFlow and AtScale derive joins from entities / level bindings; Cube and LookML declare them inline; Snowflake and GoodData sit in between. OSI's relationships[] block gives every consumer the same four fields — name, from_dataset, to_dataset, foreign_key — plus explicit cardinality, which only Cube and LookML currently declare.
5 · Time Semantics Layer (granularity)
How each product marks a time dimension and expresses granularity. OSI's is_time + granularity is the smallest common denominator.
fields[].dimension.is_timetype: timetype: timetype: TIMEdimension_group: { type: time }dataType: dateTime + date tablefields[].dimension.granularitytime_granularity: daydimensions[].granularitytimeframes: [date, week, month]DATE_TRUNC(...))DATE_TRUNC(...))LookML's dimension_group with timeframes is the most complete; Snowflake leaves time entirely to SQL. OSI collapses this into a single time field with is_time: true and a granularity value — downstream tools that want day / week / month / quarter / year can generate them from the base field plus granularity metadata, so nothing is lost and every consumer can test one flag.
6 · AI Context Layer (OSI's differentiator)
The one layer where OSI leads the ecosystem. Only Snowflake Semantic Views has native equivalents today.
fields[].ai_contextWITH SYNONYMS = ('…')column.synonyms (Q&A)metrics[].ai_contextWITH SYNONYMS = ('…')measure.synonyms (Q&A)AI_SQL_GENERATION '<instr>'AI_VERIFIED_QUERIES (…)This is the layer OSI was built for. Snowflake shipped WITH SYNONYMS, AI_SQL_GENERATION and AI_VERIFIED_QUERIES in 2026 — and no other mainstream semantic layer has an equivalent yet. OSI standardizes those hints into ai_context on every field and metric, so an agent reading OSI can find synonyms, natural-language names and verified sample queries the same way whether the source stack is Snowflake, Cube or a home-grown YAML store. When downstream tools adopt OSI, the AI-grounding metadata travels with the metric — instead of being locked inside one vendor's SQL dialect.
What OSI enables for data teams
Four patterns teams unlock once their semantic layer speaks one vendor-neutral format — from the terminal to the chat interface.
One metric definition across every BI tool
metrics[].aggregation, fields[] and relationships[] into a vendor-neutral contract. The same revenue or retention definition ships to Cube, Looker, Metabase and a Python notebook without silent drift. Validate conversions in the OSI Playground.Ground AI agents in business semantics
ai_context on every field and metric. Datus-Chat and the model layer read the same grounding, so "ARR" resolves to annual recurring revenue — not an airport code.Move between semantic layers without rewriting
Catch schema drift before dashboards break
dataset.source, relationships[] or metrics[].filter changed. Governance checks run against the spec from the CLI, not against vendor-specific YAML. See how this fits into Datus features.Frequently asked questions
LookML, Snowflake AI context, Cube joins, dimension_group timeframes, round-tripping and MAQL — how OSI handles each.
Can LookML metrics be represented in OSI?
Yes. Every LookML measure translates to an OSI metric: the type becomes aggregation, sql becomes expression, filters becomes filter. LookML's derived measures (type: number with references) map to OSI derived metrics that reference other metric names in the same file.
Does OSI support Snowflake Semantic Views' WITH SYNONYMS and AI_SQL_GENERATION?
Yes — this is the layer OSI standardizes most aggressively. WITH SYNONYMS on a dimension or metric maps directly to OSI's ai_context.synonyms; AI_SQL_GENERATION and AI_VERIFIED_QUERIES have first-class slots so agents from any vendor can read the same grounding hints.
How does OSI represent Cube's joins[] block?
Cube's joins[] entries become OSI relationships[] entries. joins[].sql becomes foreign_key, joins[].relationship (many_to_one / one_to_many) becomes cardinality, and the target cube becomes to_dataset. No inference required — the mapping is 1:1.
Is there anything in MetricFlow that OSI can't express today?
OSI v0.2 covers all core MetricFlow constructs — semantic_models, measures, dimensions, entities, top-level metrics — but a few advanced surfaces (saved queries, cumulative metrics with grain-to-date, some conversion metric options) are still evolving. The Datus Playground surfaces any dropped fields explicitly so nothing is lost silently.
Does OSI have an equivalent to LookML's dimension_group timeframes?
OSI collapses the LookML dimension_group into a single time field with is_time: true and a granularity value. Downstream tools that want all timeframes (date, week, month, quarter, year) generate them from the base field plus the granularity metadata, which keeps OSI vendor-neutral without losing information.
Can I round-trip: MetricFlow → OSI → LookML?
OSI is primarily an interchange and consumption format today. Forward conversion from MetricFlow or Cube into OSI is well supported (see the Datus Playground); back-conversion into LookML or MetricFlow-native YAML is on the community roadmap. In practice most teams treat OSI as the shared read layer and keep authoring in their source-of-truth tool.
Will OSI ever support GoodData MAQL expressions?
MAQL survives via metrics[].expression.dialects[]: the raw MAQL string is preserved under its own dialect, so a GoodData-aware consumer can still execute it while non-GoodData consumers fall back to the SQL dialect. This is the same mechanism OSI uses for any vendor-specific expression language.
When will the Datus Playground support conversion beyond MetricFlow?
MetricFlow → OSI shipped first because dbt semantic-layer YAML is the most common starting point. Cube and LookML converters are next on the roadmap; contributions are welcome — the Playground is Apache 2.0 and every converter is a pure browser-side function.
Try the OSI Playground.
Paste your MetricFlow YAML, get OSI back — validation, conversion and diff all run in your browser.