Skip to content

Commit

Permalink
add semantic models (#444)
Browse files Browse the repository at this point in the history
* add semantic models

* changelog

* add entities, remove dead code

* reduce entity fields
  • Loading branch information
emmyoop authored Aug 9, 2023
1 parent 579b24d commit af820a3
Show file tree
Hide file tree
Showing 18 changed files with 290 additions and 40 deletions.
6 changes: 6 additions & 0 deletions .changes/unreleased/Docs-20230807-152548.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Docs
body: Display semantic model details in docs
time: 2023-08-07T15:25:48.711627-05:00
custom:
Author: emmyoop
Issue: "431"
4 changes: 4 additions & 0 deletions src/app/components/graph/graph-launcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ angular
var nodes = graph.showFullGraph('exposure:' + node.name);
} else if (node && node.resource_type == 'metric') {
var nodes = graph.showFullGraph('metric:' + node.name);
} else if (node && node.resource_type == 'semantic_model') {
var nodes = graph.showFullGraph('semantic_model:' + node.name);
} else {
var nodes = graph.showFullGraph(node_name);
}
Expand All @@ -170,6 +172,8 @@ angular
var nodes = graph.showVerticalGraph('exposure:' + node.name, true);
} else if (node && node.resource_type == 'metric') {
var nodes = graph.showVerticalGraph('metric:' + node.name, true);
} else if (node && node.resource_type == 'semantic_model') {
var nodes = graph.showVerticalGraph('semantic_model:' + node.name, true);
} else {
var nodes = graph.showVerticalGraph(node.name, true);
}
Expand Down
11 changes: 11 additions & 0 deletions src/app/components/model_tree/model_tree.html
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,17 @@
</ul>
<br />
</div>

<div ng-show="tree.semantic_models.length > 0">
<strong>Semantic Models</strong>
<ul style="display: block">
<model-tree-line
item="item"
resource-type="semantic_model"
ng-repeat="item in tree.semantic_models"></model-tree-line>
</ul>
<br />
</div>

<strong>Projects</strong>
<ul>
Expand Down
10 changes: 6 additions & 4 deletions src/app/components/references/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,15 @@ angular
} else if (type == 'analysis') {
return 'Analyses';
} else if (type == 'macro') {
return 'Macros';
return 'Macros';
} else if (type == 'exposure') {
return 'Exposures';
return 'Exposures';
} else if (type == 'metric') {
return 'Metrics';
return 'Metrics';
} else if (type == 'semantic_model') {
return 'Semantic Models';
} else if (type == 'operation') {
return 'Operations';
return 'Operations';
} else {
return 'Nodes';
}
Expand Down
2 changes: 2 additions & 0 deletions src/app/components/search/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ angular
return model.package_name + "." + model.name;
} else if (model.resource_type == 'metric') {
return model.label;
} else if (model.resource_type == 'semantic_model') {
return model.name;
} else if (model.resource_type == 'exposure') {
return model.label;
} else if (model.resource_type == 'model' && model.version != null) {
Expand Down
1 change: 1 addition & 0 deletions src/app/docs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ require('./macro');
require('./analysis');
require('./exposure');
require('./metric');
require('./semantic_model');
require('./operation');
4 changes: 0 additions & 4 deletions src/app/docs/metric.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@ angular
$scope.parents = dag_utils.getParents(project, metric);
$scope.parentsLength = $scope.parents.length;

$scope.versions = {
'Definition': codeService.generateMetricSQL($scope.metric)
}

const metric_type = $scope.metric.type === 'expression'
? 'Expression metric'
: 'Aggregate metric';
Expand Down
97 changes: 97 additions & 0 deletions src/app/docs/semantic_model.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<style>
/* TODO */
.section-target {
top: -8em;
}

.noflex {
flex: 0 0 160px !important;
}

.highlight {
color: #24292e;
background-color: white;
}

</style>

<div class='app-scroll'>
<div class="app-links app-sticky">
<div class="app-title">
<div class="app-frame app-pad app-flush-bottom">

<h1>
<span class="break">{{ semantic_model.name }}</span>
<small>semantic_model</small>

<div class='clearfix'></div>
</h1>

</div>
</div>
<div class="app-frame app-pad-h">
<ul class="nav nav-tabs">
<li ui-sref-active='active'><a ui-sref="dbt.semantic_model({'#': 'details'})">Details</a></li>
<li ui-sref-active='active'><a ui-sref="dbt.semantic_model({'#': 'description'})">Description</a></li>
<li ui-sref-active='active' ng-show = "parentsLength != 0"><a ui-sref="dbt.semantic_model({'#': 'depends_on'})">Depends On</a></li>
</ul>
</div>
</div>
<div class="app-details">
<div class="app-frame app-pad">

<section class="section">
<div class="section-target" id="details"></div>
<table-details model="semantic_model" extras="extra_table_fields" />
</section>

<section class="section">
<div class="section-target" id="description"></div>
<div class="section-content">
<h6>Description</h6>
<div class="panel">
<div class="panel-body">
<div ng-if="semantic_model.description" class="model-markdown" marked="semantic_model.description"></div>
<div ng-if="!semantic_model.description">This {{ semantic_model.resource_type }} is not currently documented</div>
</div>
</div>
</div>
</section>

<section class="section" ng-show = "semantic_model.entities.length != 0">
<div class="section-target" id="entities"></div>
<div class="section-content">
<h6>Entities</h6>

<div class="panel">
<div class="detail-group" style="padding-bottom: 0">
<div class="detail-body" style="padding-left: 0">
<dl class="detail" ng-style="{'padding-left': $index == 0 ? 0 : 'auto'}"
ng-repeat="entity in semantic_model.entities">
<dt class="detail-label">Name</dt>
<dd class="detail-value" ng-if="entity.name">{{ entity.name }}</dd>
<dd class="detail-value" ng-if="!entity.name">None</dd>
<dt class="detail-label">Type</dt>
<dd class="detail-value" ng-if="entity.type">{{ entity.type }}</dd>
<dd class="detail-value" ng-if="!entity.type">None</dd>
<dt class="detail-label">Expression</dt>
<dd class="detail-value" ng-if="entity.expr">{{ entity.expr }}</dd>
<dd class="detail-value" ng-if="!entity.expr">None</dd>
</dl>
</div>
</div>
</div>
</div>
</section>

<section class="section" ng-show = "parentsLength != 0">
<div class="section-target" id="depends_on"></div>
<div class="section-content">
<h6>Depends On</h6>
<reference-list references="parents" node="semantic_model" />
</div>
</section>

</div>
</div>
</div>
42 changes: 42 additions & 0 deletions src/app/docs/semantic_model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
'use strict';

const angular = require('angular');
const dag_utils = require('./dag_utils')
require("./styles.css");

angular
.module('dbt')
.controller('SemanticModelCtrl', ['$scope', '$state', 'project', 'code', '$anchorScroll', '$location',
function($scope, $state, projectService, codeService, $anchorScroll, $location) {

$scope.model_uid = $state.params.unique_id;
$scope.project = projectService;

$scope.codeService = codeService;
$scope.extra_table_fields = [];
$scope.versions = {};

$scope.semantic_model = {};
projectService.ready(function(project) {
let semantic_model = project.nodes[$scope.model_uid];
$scope.semantic_model = semantic_model;
$scope.parents = dag_utils.getParents(project, semantic_model);
$scope.parentsLength = $scope.parents.length;

const semantic_model_type = $scope.semantic_model.type === 'expression'
? 'Expression semantic_model'
: 'Aggregate semantic_model';

$scope.extra_table_fields = [
{
name: "Semantic Model Type",
value: semantic_model_type,
},
{
name: "Semantic Model name",
value: $scope.semantic_model.name
}
]

})
}]);
2 changes: 2 additions & 0 deletions src/app/graph/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ angular
return 'exposure:' + node.name;
} else if (node && node.resource_type == 'metric') {
return 'metric:' + node.name;
} else if (node && node.resource_type == 'semantic_model') {
return 'semantic_model:' + node.name;
} else if (node && node.resource_type == 'model' && node.version != null) {
return node.label;
} else if (node.name) {
Expand Down
9 changes: 9 additions & 0 deletions src/app/index.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const templates = {
macro: require('./docs/macro.html'),
exposure: require('./docs/exposure.html'),
metric: require('./docs/metric.html'),
semantic_model: require('./docs/semantic_model.html'),
operation: require('./docs/operation.html'),
}

Expand Down Expand Up @@ -133,6 +134,14 @@ angular
unique_id: {type: 'string'}
},
})
.state('dbt.semantic_model', {
url: 'semantic_model/:unique_id?section&' + graph_params,
controller: 'SemanticModelCtrl',
templateUrl: templates.semantic_model,
params: {
unique_id: {type: 'string'}
},
})
.state('dbt.operation', {
url: 'operation/:unique_id?section&' + graph_params,
controller: 'OperationCtrl',
Expand Down
1 change: 1 addition & 0 deletions src/app/main/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ angular
$scope.tree.sources = tree.sources;
$scope.tree.exposures = tree.exposures;
$scope.tree.metrics = tree.metrics;
$scope.tree.semantic_models = tree.semantic_models;
$scope.tree.groups = tree.groups;

setTimeout(function() {
Expand Down
22 changes: 0 additions & 22 deletions src/app/services/code_service.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,28 +62,6 @@ angular
return query.join("\n");
}

service.generateMetricSQL = function(metric) {
if (metric.calculation_method == 'derived') {
return "-- derived\n" + metric.expression;
}

const queryParts = [
`select ${metric.calculation_method}(${metric.expression})` ,
`from {{ ${metric.model} }}`,
];

if (metric.filters.length > 0) {
const filterExprs = metric.filters.map(filter => (
`${filter.field} ${filter.operator} ${filter.value}`
));

const filters = filterExprs.join(' AND ');
queryParts.push(`where ${filters}`);
}

return queryParts.join('\n');
}

return service;

}]);
13 changes: 10 additions & 3 deletions src/app/services/graph.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,13 @@ angular
'border-color': '#ff5688',
}
},
{
selector: 'node[resource_type="semantic_model"]',
style: {
'background-color': '#ffa8c2',
'border-color': '#ffa8c2',
}
},
{
selector: 'node[language="python"]',
style: {
Expand Down Expand Up @@ -372,8 +379,8 @@ angular


_.each(_.filter(service.manifest.nodes, function(node) {
// operation needs to be a graph type so that the parent/child mpa can be resolved even though we won't be displaying it
var is_graph_type = _.includes(['model', 'seed', 'source', 'snapshot', 'analysis', 'exposure', 'metric', 'operation'], node.resource_type);
// operation needs to be a graph type so that the parent/child map can be resolved even though we won't be displaying it
var is_graph_type = _.includes(['model', 'seed', 'source', 'snapshot', 'analysis', 'exposure', 'metric', 'semantic_model', 'operation'], node.resource_type);
var is_singular_test = node.resource_type == 'test' && !node.hasOwnProperty('test_metadata');
return is_graph_type || is_singular_test;
}), function(node) {
Expand All @@ -394,7 +401,7 @@ angular
var parent_node = service.manifest.nodes[parent];
var child_node = service.manifest.nodes[child];

if (!_.includes(['model', 'source', 'seed', 'snapshot', 'metric'], parent_node.resource_type)) {
if (!_.includes(['model', 'source', 'seed', 'snapshot', 'metric', 'semantic_model'], parent_node.resource_type)) {
return;
} else if (child_node.resource_type == 'test' && child_node.hasOwnProperty('test_metadata')) {
return;
Expand Down
9 changes: 6 additions & 3 deletions src/app/services/node_selection_service.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ angular
'test',
'analysis',
'exposure',
'metric'
'metric',
'semantic_model'
],
depth: 1,
};
Expand All @@ -36,7 +37,7 @@ angular
options: {
packages: [],
tags: [null],
resource_types: ['model', 'seed', 'snapshot', 'source', 'test', 'analysis', 'exposure', 'metric'],
resource_types: ['model', 'seed', 'snapshot', 'source', 'test', 'analysis', 'exposure', 'metric', 'semantic_model'],
}
};

Expand All @@ -60,6 +61,8 @@ angular
include_selection = '+exposure:' + node.name;
} else if (node && node.resource_type == 'metric') {
include_selection = '+metric:' + node.name;
} else if (node && node.resource_type == 'semantic_model') {
include_selection = '+semantic_model:' + node.name;
} else if (node && _.includes(['analysis', 'test'], node.resource_type)) {
include_selection = '+' + node.name;
} else {
Expand Down Expand Up @@ -92,7 +95,7 @@ angular
if (node.resource_type == 'source') {
pre += "source:"
node_name = node.source_name + "." + node.name;
} else if (['exposure', 'metric'].indexOf(node.resource_type) > -1) {
} else if (['exposure', 'metric', 'semantic_model'].indexOf(node.resource_type) > -1) {
pre += node.resource_type + ":"
node_name = node.name;
} else {
Expand Down
Loading

0 comments on commit af820a3

Please sign in to comment.