🤝Relationships

In Euno, the data model is made up of resources, each identified with a Universal Resource Identifier. Between these resources there are relationships.

These relationships form the foundation of Euno’s graph-based understanding of the data stack. There are three primary types of relationships:

1. Dependency

A dependency relationship exists when one resource relies on another. For example, a database view created by joining three tables will have three dependency relationships pointing from the view to each table.

If resource A depends on resource B, A is said to be downstream of B, and B is upstream of A.

A single resource may have zero, one, or many dependencies—technically a many-to-many relationship.

Examples of using upstream and downstream queries:

  • To find the upstream of a resource: has upstream(uri="<resource-uri>")

  • To find the downstream of a resource: has downstream(uri="<resource-uri>")

Field-Level Dependencies

Euno also supports fine-grained, field-level dependency tracking using the attributes upstream_fields and downstream_fields. These relationships capture dependencies between individual fields (such as columns, measures, or dimensions), or between fields and visualizations (such as Tableau views or Looker Looks).

For instance:

  • A column in a table used in a Tableau view would create a dependency from the view to the column.

  • A measure in a Looker Look based on multiple columns would be downstream of those columns.

Examples of using upstream_fields and downstream_fields:

  • To find the visualizations in Tableau that use a specific field: type="tableau_view" and has upstream_fields(uri="<resource-uri>")

  • To find all the fields used in a Tableau view: type="tableau_field" and has downstream_fields(uri="<resource-uri>")

Note: If a resource has both field-level lineage and regular lineage, and you want to return all relevant resources, you need to include both types of queries. For example: has downstream_fields(uri="<resource-uri>") or has downstream(uri="<resource-uri>")

2. Containment

A resource can be contained within another resource. For example, a column is contained in a table, and a table is contained in a schema.

When two resources, A and B, have a containment relationship such that A contains B, we say that A is the parent of B, and B is a child of A.

A resource can have zero, one, or many children, and zero or one parent. In technical terms, this is an optional many-to-one relationship.

Examples using the containment relationship:

  • To find all the resources inside a workbook: has parent(type="tableau_workbook" and uri="<resource-uri>")

  • To return all the fields in a table: has parent(type="table" and uri="<resource-uri>")

3. Defined-by

The defined by relationship links a resource to the entity that defines it. It is used when one resource determines the structure or existence of another.

For example, a Snowflake table created via a dbt model will have a defined by relationship pointing from the table to the dbt model. Conversely, the dbt model is considered the definer of the table.

It is possible for a resource to have multiple definers.

Example:

  • To find the dbt resource that defines a specific table in the warehouse: type~"dbt" and has defined(type="table" and uri="<resource-uri>") or type~"dbt" and is definer of(type="table" and uri="<resource-uri>")

  • To find the table that is defined by a dbt model: type="table" and has definer(type~"dbt" and uri="<resource-uri>") or type="table" and is defined by(type~"dbt" and uri="<resource-uri>")

This relationship helps trace logical definitions across tools, and surfaces authoritative sources within your data stack.

Summary of Resources and Possible Relationships

Lineage Relationships (is upstream of)

Source Resource
Relationship
Target Resource

dbt_seed, dbt_source, dbt_model, dbt_snapshot

is upstream of

dbt_model, dbt_snapshot

dbt_measure

is upstream of

dbt_metric

dbt_metric

is upstream of

table, dbt_metric, looker_view

table

is upstream of

table,

tableau_published_data_source, tableau_embedded_data_source, tableau_custom_sql, looker_view

tableau_custom_sql

is upstream of

tableau_embedded_data_source, tableau_published_data_source

tableau_published_data_source

is upstream of

tableau_embedded_data_source

tableau_embedded_data_source

is upstream of

tableau_view

tableau_view

is upstream of

tableau_dashboard

looker_view

is upstream of

looker_view, looker_explore

looker_explore

is upstream of

looker_view, looker_explore, looker_look, looker_tile, looker_dashboard

looker_tile

is upstream of

looker_dashboard

looker_look

is upstream of

looker_dashboard

Field-Level Lineage Relationships (is upstream_fields of)

Source Field
Relationship
Target Field

column

is upstream_fields of

column, tableau_field

tableau_field

is upstream_fields of

tableau_field, tableau_view

Hierarchical Relationships (is parent of)

Parent Resource
Relationship
Child Resource

table

is parent of

column

dbt_model

is parent of

column, dbt_dimension, dbt_measure, dbt_metric

dbt_project

is parent of

dbt_seed, dbt_source, dbt_model, dbt_snapshot

tableau_project

is parent of

tableau_published_data_source, tableau_workbook

tableau_workbook

is parent of

tableau_embedded_data_source, tableau_dashboard, tableau_view

tableau_published_data_source

is parent of

tableau_custom_sql,

tableau_field

tableau_embedded_data_source

is parent of

tableau_custom_sql,

tableau_field

looker_view

is parent of

looker_dimension, looker_measure

looker_look

is parent of

looker_dimension, looker_measure

looker_tile

is parent of

looker_dimension, looker_measure

looker_folder

is parent of

looker_dashboard, looker_look

looker_dashboard

is parent of

looker_tile

Definition Relationship (is defined by)

Source Field
Relationship
Target Field

table

is defined by

dbt_seed, dbt_source, dbt_model, dbt_snapshot

Last updated