Skip to content

Commit

Permalink
exposures on non public models - more files
Browse files Browse the repository at this point in the history
  • Loading branch information
dave-connors-3 committed May 11, 2023
1 parent c903f46 commit 3de4e66
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 5 deletions.
69 changes: 67 additions & 2 deletions docs/rules/governance.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Models with public access are free to be consumed by any downstream consumer. Th
Edit the yml to include the contract configuration, as well as a column entry for all columns output by the model, including their datatype. While not strictly required for defining a contracts, it's best practice to also document each column as well.

```yml

models:
- name: report_1
description: very important OKR reporting model
access: public
Expand Down Expand Up @@ -69,7 +69,7 @@ Models with public access are free to be consumed by any downstream consumer. Th
Edit the yml to include a model level description, as well as a column entry with a description for all columns output by the model. While not strictly required for public models, these should likely also have contracts added as well. (See above rule)

```yml
models:
- name: report_1
description: very important OKR reporting model
access: public
Expand All @@ -82,3 +82,68 @@ Edit the yml to include a model level description, as well as a column entry wi
description: the primary key of my OKR model
data_type: integer
```

## Exposures dependent on private models

`fct_exposures_dependent_on_private_models` ([source](https://github.com/dbt-labs/dbt-project-evaluator/blob/main/models/marts/governance/fct_exposures_dependent_on_private_models.sql)) shows each relationship between a resource and an exposure where the parent resource is not a model with `access` configured as public.

**Example**

Here's a sample DAG that shows direct exposure relationships.

![An example exposure with a two parents (fct_model_6 and dim_model_7)](https://user-images.githubusercontent.com/73915542/178068955-742e2c87-4385-48f9-b9fb-94a1cbc8079a.png){ width=500 }

If this were the yml for these two parent models, `dim_model_7` would be flagged by this model, as it is not a public model.

```yml
models:
- name: fct_model_6
description: very important OKR reporting model
access: public
config:
materialized: table
contract:
enforced: true
columns:
- name: id
description: the primary key of my OKR model
data_type: integer
- name: dim_model_7
description: excellent model
access: private
```


**Reason to Flag**

Exposures show how and where your data is being consumed in downstream tools. These tools should read from public, trusted, contracted data sources. All models that are exposed to other tools should have that codified in their `access` configuration.

**How to Remediate**

Edit the yml to include fully expose the models that your exposures depend on. This should include `access`, a full model contract, and descriptions at all levels of the model.

```yml
models:
- name: fct_model_6
description: very important OKR reporting model
access: public
config:
materialized: table
contract:
enforced: true
columns:
- name: id
description: the primary key of my OKR model
data_type: integer
- name: dim_model_7
description: excellent model
access: public
config:
materialized: table
contract:
enforced: true
columns:
- name: id
description: the primary key of my excellent model
data_type: integer
```
25 changes: 24 additions & 1 deletion macros/recursive_dag.sql
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ all_relationships (
parent_resource_type,
parent_model_type,
parent_materialized,
parent_access,
parent_is_public,
parent_source_name,
parent_file_path,
parent_directory_path,
Expand All @@ -30,6 +32,8 @@ all_relationships (
child_resource_type,
child_model_type,
child_materialized,
child_access,
child_is_public,
child_source_name,
child_file_path,
child_directory_path,
Expand All @@ -45,6 +49,8 @@ all_relationships (
resource_type as parent_resource_type,
model_type as parent_model_type,
materialized as parent_materialized,
access as parent_access,
is_public as parent_is_public,
source_name as parent_source_name,
file_path as parent_file_path,
directory_path as parent_directory_path,
Expand All @@ -54,6 +60,8 @@ all_relationships (
resource_type as child_resource_type,
model_type as child_model_type,
materialized as child_materialized,
access as child_access,
is_public as child_is_public,
source_name as child_source_name,
file_path as child_file_path,
directory_path as child_directory_path,
Expand All @@ -74,6 +82,8 @@ all_relationships (
all_relationships.parent_resource_type as parent_resource_type,
all_relationships.parent_model_type as parent_model_type,
all_relationships.parent_materialized as parent_materialized,
all_relationships.parent_access as parent_access,
all_relationships.parent_is_public as parent_is_public,
all_relationships.parent_source_name as parent_source_name,
all_relationships.parent_file_path as parent_file_path,
all_relationships.parent_directory_path as parent_directory_path,
Expand All @@ -83,6 +93,8 @@ all_relationships (
direct_relationships.resource_type as child_resource_type,
direct_relationships.model_type as child_model_type,
direct_relationships.materialized as child_materialized,
direct_relationships.access as child_access,
direct_relationships.is_public as child_is_public,
direct_relationships.source_name as child_source_name,
direct_relationships.file_path as child_file_path,
direct_relationships.directory_path as child_directory_path,
Expand Down Expand Up @@ -139,7 +151,10 @@ with direct_relationships as (
resource_id as parent_id,
resource_id as child_id,
resource_name,
materialized as child_materialized
materialized as child_materialized,
is_public as child_is_public,
access as child_access

from direct_relationships
)

Expand All @@ -148,6 +163,8 @@ with direct_relationships as (
parent_id,
child_id,
child_materialized,
child_is_public,
child_access,
0 as distance,
{{ dbt.array_construct(['resource_name']) }} as path,
cast(null as boolean) as is_dependent_on_chain_of_views
Expand All @@ -161,6 +178,8 @@ with direct_relationships as (
cte_{{i - 1}}.parent_id as parent_id,
direct_relationships.resource_id as child_id,
direct_relationships.materialized as child_materialized,
direct_relationships.is_public as child_is_public,
direct_relationships.access as child_access,
cte_{{i - 1}}.distance+1 as distance,
{{ dbt.array_append(prev_cte_path, 'direct_relationships.resource_name') }} as path,
case
Expand Down Expand Up @@ -196,6 +215,8 @@ with direct_relationships as (
parent.resource_type as parent_resource_type,
parent.model_type as parent_model_type,
parent.materialized as parent_materialized,
parent.is_public as parent_is_public,
parent.access as parent_access,
parent.source_name as parent_source_name,
parent.file_path as parent_file_path,
parent.directory_path as parent_directory_path,
Expand All @@ -205,6 +226,8 @@ with direct_relationships as (
child.resource_type as child_resource_type,
child.model_type as child_model_type,
child.materialized as child_materialized,
child.is_public as child_is_public,
child.access as child_access,
child.source_name as child_source_name,
child.file_path as child_file_path,
child.directory_path as child_directory_path,
Expand Down
2 changes: 2 additions & 0 deletions models/marts/core/int_direct_relationships.sql
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ all_graph_resources as (
file_name,
model_type,
materialized,
is_public,
access,
source_name
from {{ ref('int_all_graph_resources') }}
),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
with

direct_exposure_relationships as (
select * from {{ ref('int_all_dag_relationships') }}
where
distance = 1
and child_resource_type = 'exposure'
and not (
parent_resource_type = 'model'
and parent_is_public
)
),

final as (

select
child as exposure_name,
parent as parent_resource_name,
parent_access,
parent_resource_type

from direct_exposure_relationships

)

select * from final

{{ filter_exceptions(this) }}
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@ final as (
and not is_contract_enforced
)

select * from final
select * from final

{{ filter_exceptions(this) }}
4 changes: 3 additions & 1 deletion models/marts/governance/fct_undocumented_public_models.sql
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,6 @@ final as (
)
)

select * from final
select * from final

{{ filter_exceptions(this) }}
5 changes: 5 additions & 0 deletions models/marts/governance/governance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,10 @@ models:

- name: fct_undocumented_public_models
description: "This table shows each public model that does not have both a model level description, and a description for each of the columns in the model"
tests:
- is_empty

- name: fct_exposures_dependent_on_private_models
description: "This table shows each direct relationship between a parent resource and a downstream exposure where the parent resource is not a public model"
tests:
- is_empty

0 comments on commit 3de4e66

Please sign in to comment.