Exporting
konstruct export hands the lineage to other tools:
Format |
What it writes |
Use |
|---|---|---|
|
One OpenLineage |
Load into Marquez, DataHub, OpenMetadata or any OpenLineage consumer |
|
A |
Documentation, pull requests, GitHub renders it inline |
|
A Graphviz graph, with column ports under |
Large static diagrams |
|
One row per column edge: relation, column, upstream relation and column, transform, verification and expression |
Spreadsheets, or a lineage table in the warehouse |
|
The ontology as an Apache Ossie semantic model: datasets, relationships, and each measure as a metric with its composed formula and a |
Semantic layers and BI tools that read Ossie |
|
The ontology as OWL 2 in Turtle: entities as classes, their columns as data properties, relationships as object properties, and measures as annotations (see below) |
Knowledge graphs, ontology editors and platforms that import RDF |
|
The ontology as one Snowflake |
Snowflake semantic views and Cortex Analyst |
|
The ontology as Databricks metric views, one |
Unity Catalog metric views |
A plugin the project enables can add a format, which konstruct export <format> writes as it does these.
konstruct export openlineage -o lineage.jsonl --namespace duckdb://analytics
konstruct export mermaid -s orders.amount --columns > docs/orders-amount.mmd
The tests validate every OpenLineage event, and its column lineage and schema facets, against the OpenLineage 2-0-2 JSON schemas.
The Ontology for Each Platform
ossie, owl, semantic-view and metric-view write the same ontology, so one ontology, derived from the code and definitions.yml, feeds each platform in its own format. They carry the same entities: each relation that holds an entity is a dataset, a logical table or a metric view keyed by the entity’s key, and in OWL the entity is a class. A project with no definitions.yml exports the entities and relationships Konstruct derives from keys, tests and joins, and the entities and measures of any ontology pack it matches. Nothing is invented: a description, synonym, grain or filter is written only when the ontology holds it. Each export takes the whole ontology, so --select does not apply, and an ontology with no entities or measures, or whose every measure is left out, exports nothing, says why, and exits with status 1.
The owl, semantic-view and metric-view files open with comments that list what each leaves out and why; the ossie export names each measure it leaves out on standard error (see Apache Ossie Models). The ossie, semantic-view and metric-view exports leave out, and owl writes without its formula, a measure whose composed formula, by what the graph records of the queries on the way, would count other rows than the measure does. Each relation on the way from the measure’s column down to source columns is checked:
a
WHERE,HAVING,QUALIFY,LIMIT,OFFSET,DISTINCT, anti join,UNIONthat removes duplicates,INTERSECTorEXCEPTchanges the rows;a join keeps them only when the joined side’s column is known to be unique (a
uniquetest, a primary key or an identifier field), so that it matches at most one row;an inner join, or an outer join that reads the measure’s table only on its nullable side (or joins it through such a table), also drops rows unless a
not_nulltest and arelationshipstest on the foreign key, targeting the joined column, show that every row matches;a self join keeps them only when both its columns are unique, a join between two tables the measure reads is checked both ways, and a table read with no such join condition, as a cross join reads it, changes them;
a source that makes rows of its own anywhere in the relation’s query, a table function (
generate_series,range, a SnowflakeTABLE(FLATTEN(...))),VALUES,UNNEST,LATERALorLATERAL VIEW, changes them.
Konstruct does not record the rows a PIVOT or UNPIVOT makes or a recursive CTE adds, so a measure composed through one is not left out for them; a query whose SQL Konstruct could not analyse records nothing to check: its formula does not reach source columns, so its measure is left out for that reason.
A measure is composed from another column bound to it when its first column’s way down changes the rows. A measure that aggregates an aggregate (AVG(SUM(...))), as a formula composed across two grains does, or that combines the rows of a UNION ALL, is left out too.
konstruct export owl -o shop.ttl --namespace https://example.com/shop
konstruct export semantic-view -o semantic_view.sql
konstruct export metric-view -o metric_views.sql
OWL and Turtle
Ontology |
OWL |
|---|---|
Entity |
An |
Property |
An |
Relationship |
An |
Measure |
A named individual with its definition, synonyms ( |
Broader term |
|
IRIs are stable: each name is under the ontology’s IRI, urn:konstruct:<project> unless --namespace gives another, and an entity or measure whose term was read from a SKOS or OWL vocabulary keeps that concept’s IRI. --namespace must be an absolute IRI. Konstruct’s annotation properties are declared in the file under https://kodexlabsio.github.io/konstruct/vocabulary#. Left out: the columns of relations that hold no entity, which appear only in formulas; a key not known to be unique, such as one only a term names; the range of a date or time property, since the OWL 2 datatype map has no date or time; the ontology’s rules and violations (konstruct ontology lists them); and a broader term that is not an entity. Konstruct reads the file back as a vocabulary, each class an entity term.
Snowflake Semantic View
Ontology |
Semantic view |
|---|---|
Relation holding an entity, or read by a measure |
A logical table under |
Column |
A dimension under |
Relationship to a primary key or unique key |
|
Aggregate measure that reads one table |
A metric of that table under |
Names that differ only by case are kept apart, since unquoted Snowflake names are not case sensitive, and a reserved word is quoted. Left out: a key not known to be unique; a measure that is a per-row formula, whose formula does not reach source columns, that reads more than one table, or that the rule above leaves out; a relationship whose key is not known to be unique, that refers to a column the target does not key, that joins a table to itself, or that would close a cycle, which Snowflake does not allow; facts, since Konstruct does not tell facts from dimensions; and data types, owners, status and verification, which a semantic view has no place for.
Databricks Metric Views
Each table above is the source of one metric view, <table>_metrics, written as YAML version 1.1 inside a CREATE OR REPLACE VIEW ... WITH METRICS LANGUAGE YAML AS $$ ... $$ statement:
Ontology |
Metric view |
|---|---|
Relation |
|
Relationship to a primary key or unique key |
A join under |
Column |
A field under |
Aggregate measure that reads the source |
A measure, its formula in Databricks SQL with each column as |
Names that differ only by case are kept apart, and keywords are quoted. Left out: the same measures and relationships as the semantic view, apart from cycles, since a view joins only the tables its source refers to; a synonym or display name over 255 characters; a comment, synonym or display name that holds $$, which would end the statement; and data types, owners, status and verification.