Skip to content

Commit c90a202

Browse files
Merge pull request #143 from dbt-labs/removing_dbt_utils
Removing dbt utils dependency
2 parents 48ebccf + ae2d9f6 commit c90a202

77 files changed

Lines changed: 314 additions & 79 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
kind: Under the Hood
2+
body: Removing dbt_utils
3+
time: 2022-10-12T11:41:17.757328-05:00
4+
custom:
5+
Author: callum-mcdata
6+
Issue: "143"
7+
PR: "143"

integration_tests/models/custom_calendar.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{{ config(materialized='table') }}
22

33
with days as (
4-
{{ dbt_utils.date_spine(
4+
{{ metrics.metric_date_spine(
55
datepart="day",
66
start_date="cast('2010-01-01' as date)",
77
end_date="cast('2030-01-01' as date)"

integration_tests/packages.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
packages:
22
- local: ../
33
- package: calogica/dbt_expectations
4-
version: [">=0.5.0", "<0.6.0"]
4+
version: [">=0.6.0", "<0.7.0"]
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
{% macro metric_get_intervals_between(start_date, end_date, datepart) -%}
2+
{{ return(adapter.dispatch('metric_get_intervals_between', 'metrics')(start_date, end_date, datepart)) }}
3+
{%- endmacro %}
4+
5+
{% macro default__metric_get_intervals_between(start_date, end_date, datepart) -%}
6+
{%- call statement('metric_get_intervals_between', fetch_result=True) %}
7+
8+
select {{ datediff(start_date, end_date, datepart) }}
9+
10+
{%- endcall -%}
11+
12+
{%- set value_list = load_result('metric_get_intervals_between') -%}
13+
14+
{%- if value_list and value_list['data'] -%}
15+
{%- set values = value_list['data'] | map(attribute=0) | list %}
16+
{{ return(values[0]) }}
17+
{%- else -%}
18+
{{ return(1) }}
19+
{%- endif -%}
20+
21+
{%- endmacro %}
22+
23+
24+
{% macro metric_date_spine(datepart, start_date, end_date) %}
25+
{{ return(adapter.dispatch('metric_date_spine', 'metrics')(datepart, start_date, end_date)) }}
26+
{%- endmacro %}
27+
28+
{% macro default__metric_date_spine(datepart, start_date, end_date) %}
29+
30+
31+
{# call as follows:
32+
33+
metric_date_spine(
34+
"day",
35+
"to_date('01/01/2016', 'mm/dd/yyyy')",
36+
"dateadd(week, 1, current_date)"
37+
) #}
38+
39+
40+
with rawdata as (
41+
42+
{{metrics.metric_generate_series(
43+
metrics.metric_get_intervals_between(start_date, end_date, datepart)
44+
)}}
45+
46+
),
47+
48+
all_periods as (
49+
50+
select (
51+
{{
52+
dateadd(
53+
datepart,
54+
"row_number() over (order by 1) - 1",
55+
start_date
56+
)
57+
}}
58+
) as date_{{datepart}}
59+
from rawdata
60+
61+
),
62+
63+
filtered as (
64+
65+
select *
66+
from all_periods
67+
where date_{{datepart}} <= {{ end_date }}
68+
69+
)
70+
71+
select * from filtered
72+
73+
{% endmacro %}
74+
75+
76+
{% macro metric_get_powers_of_two(upper_bound) %}
77+
{{ return(adapter.dispatch('metric_get_powers_of_two', 'metrics')(upper_bound)) }}
78+
{% endmacro %}
79+
80+
{% macro default__metric_get_powers_of_two(upper_bound) %}
81+
82+
{% if upper_bound <= 0 %}
83+
{{ exceptions.raise_compiler_error("upper bound must be positive") }}
84+
{% endif %}
85+
86+
{% for _ in range(1, 100) %}
87+
{% if upper_bound <= 2 ** loop.index %}{{ return(loop.index) }}{% endif %}
88+
{% endfor %}
89+
90+
{% endmacro %}
91+
92+
93+
{% macro metric_generate_series(upper_bound) %}
94+
{{ return(adapter.dispatch('metric_generate_series', 'metrics')(upper_bound)) }}
95+
{% endmacro %}
96+
97+
{% macro default__metric_generate_series(upper_bound) %}
98+
99+
{% set n = metrics.metric_get_powers_of_two(upper_bound) %}
100+
101+
with p as (
102+
select 0 as generated_number union all select 1
103+
), unioned as (
104+
105+
select
106+
107+
{% for i in range(n) %}
108+
p{{i}}.generated_number * power(2, {{i}})
109+
{% if not loop.last %} + {% endif %}
110+
{% endfor %}
111+
+ 1
112+
as generated_number
113+
114+
from
115+
116+
{% for i in range(n) %}
117+
p as p{{i}}
118+
{% if not loop.last %} cross join {% endif %}
119+
{% endfor %}
120+
121+
)
122+
123+
select *
124+
from unioned
125+
where generated_number <= {{upper_bound}}
126+
order by generated_number
127+
128+
{% endmacro %}

macros/misc/metrics__equality.sql

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
{% test metric_equality(model, compare_model, compare_columns=None) %}
2+
{{ return(adapter.dispatch('test_metric_equality', 'metrics')(model, compare_model, compare_columns)) }}
3+
{% endtest %}
4+
5+
{% macro default__test_metric_equality(model, compare_model, compare_columns=None) %}
6+
7+
{% set set_diff %}
8+
count(*) + coalesce(abs(
9+
sum(case when which_diff = 'a_minus_b' then 1 else 0 end) -
10+
sum(case when which_diff = 'b_minus_a' then 1 else 0 end)
11+
), 0)
12+
{% endset %}
13+
14+
{#-- Needs to be set at parse time, before we return '' below --#}
15+
{{ config(fail_calc = set_diff) }}
16+
17+
{#-- Prevent querying of db in parsing mode. This works because this macro does not create any new refs. #}
18+
{%- if not execute -%}
19+
{{ return('') }}
20+
{% endif %}
21+
22+
-- setup
23+
{%- do metrics._metric_is_relation(model, 'test_metric_equality') -%}
24+
25+
{#-
26+
If the compare_cols arg is provided, we can run this test without querying the
27+
information schema — this allows the model to be an ephemeral model
28+
-#}
29+
30+
{%- if not compare_columns -%}
31+
{%- do metrics._metric_is_ephemeral(model, 'test_metric_equality') -%}
32+
{%- set compare_columns = adapter.get_columns_in_relation(model) | map(attribute='quoted') -%}
33+
{%- endif -%}
34+
35+
{% set compare_cols_csv = compare_columns | join(', ') %}
36+
37+
with a as (
38+
39+
select * from {{ model }}
40+
41+
),
42+
43+
b as (
44+
45+
select * from {{ compare_model }}
46+
47+
),
48+
49+
a_minus_b as (
50+
51+
select {{compare_cols_csv}} from a
52+
{{ except() }}
53+
select {{compare_cols_csv}} from b
54+
55+
),
56+
57+
b_minus_a as (
58+
59+
select {{compare_cols_csv}} from b
60+
{{ except() }}
61+
select {{compare_cols_csv}} from a
62+
63+
),
64+
65+
unioned as (
66+
67+
select 'a_minus_b' as which_diff, a_minus_b.* from a_minus_b
68+
union all
69+
select 'b_minus_a' as which_diff, b_minus_a.* from b_minus_a
70+
71+
)
72+
73+
select * from unioned
74+
75+
{% endmacro %}
76+
77+
78+
{% macro _metric_is_relation(obj, macro) %}
79+
{%- if not (obj is mapping and obj.get('metadata', {}).get('type', '').endswith('Relation')) -%}
80+
{%- do exceptions.raise_compiler_error("Macro " ~ macro ~ " expected a Relation but received the value: " ~ obj) -%}
81+
{%- endif -%}
82+
{% endmacro %}
83+
84+
{% macro _metric_is_ephemeral(obj, macro) %}
85+
{%- if obj.is_cte -%}
86+
{% set ephemeral_prefix = api.Relation.add_ephemeral_prefix('') %}
87+
{% if obj.name.startswith(ephemeral_prefix) %}
88+
{% set model_name = obj.name[(ephemeral_prefix|length):] %}
89+
{% else %}
90+
{% set model_name = obj.name %}
91+
{%- endif -%}
92+
{% set error_message %}
93+
The `{{ macro }}` macro cannot be used with ephemeral models, as it relies on the information schema.
94+
95+
`{{ model_name }}` is an ephemeral model. Consider making it a view or table instead.
96+
{% endset %}
97+
{%- do exceptions.raise_compiler_error(error_message) -%}
98+
{%- endif -%}
99+
{% endmacro %}

models/dbt_metrics_default_calendar.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{{ config(materialized='table') }}
22

33
with days as (
4-
{{ dbt_utils.date_spine(
4+
{{ metrics.metric_date_spine(
55
datepart="day",
66
start_date="cast('1990-01-01' as date)",
77
end_date="cast('2030-01-01' as date)"

packages.yml

Lines changed: 0 additions & 3 deletions
This file was deleted.

tests/functional/base_metric_types/test_base_average_metric.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
fact_orders_source_csv,
99
fact_orders_sql,
1010
fact_orders_yml,
11+
packages_yml
1112
)
1213

1314
# models/base_average_metric.sql
@@ -26,7 +27,7 @@
2627
models:
2728
- name: base_average_metric
2829
tests:
29-
- dbt_utils.equality:
30+
- metrics.metric_equality:
3031
compare_model: ref('base_average_metric__expected')
3132
metrics:
3233
- name: base_average_metric

tests/functional/base_metric_types/test_base_count_distinct_metric.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
models:
2727
- name: base_count_distinct_metric
2828
tests:
29-
- dbt_utils.equality:
29+
- metrics.metric_equality:
3030
compare_model: ref('base_count_distinct_metric__expected')
3131
3232
metrics:

tests/functional/base_metric_types/test_base_count_metric.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
models:
2727
- name: base_count_metric
2828
tests:
29-
- dbt_utils.equality:
29+
- metrics.metric_equality:
3030
compare_model: ref('base_count_metric__expected')
3131
metrics:
3232
- name: base_count_metric

0 commit comments

Comments
 (0)