dbt-adapters 0.1.0a1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of dbt-adapters might be problematic. Click here for more details.
- dbt/__init__.py +0 -0
- dbt/adapters/__about__.py +1 -0
- dbt/adapters/__init__.py +7 -0
- dbt/adapters/base/README.md +13 -0
- dbt/adapters/base/__init__.py +15 -0
- dbt/adapters/base/column.py +166 -0
- dbt/adapters/base/connections.py +426 -0
- dbt/adapters/base/impl.py +1654 -0
- dbt/adapters/base/meta.py +131 -0
- dbt/adapters/base/plugin.py +32 -0
- dbt/adapters/base/query_headers.py +101 -0
- dbt/adapters/base/relation.py +471 -0
- dbt/adapters/cache.py +521 -0
- dbt/adapters/capability.py +52 -0
- dbt/adapters/clients/__init__.py +0 -0
- dbt/adapters/clients/jinja.py +24 -0
- dbt/adapters/contracts/__init__.py +0 -0
- dbt/adapters/contracts/connection.py +228 -0
- dbt/adapters/contracts/macros.py +11 -0
- dbt/adapters/contracts/relation.py +125 -0
- dbt/adapters/events/README.md +57 -0
- dbt/adapters/events/__init__.py +0 -0
- dbt/adapters/events/adapter_types.proto +517 -0
- dbt/adapters/events/adapter_types_pb2.py +208 -0
- dbt/adapters/events/base_types.py +40 -0
- dbt/adapters/events/logging.py +83 -0
- dbt/adapters/events/types.py +423 -0
- dbt/adapters/exceptions/__init__.py +40 -0
- dbt/adapters/exceptions/alias.py +24 -0
- dbt/adapters/exceptions/cache.py +68 -0
- dbt/adapters/exceptions/compilation.py +255 -0
- dbt/adapters/exceptions/connection.py +16 -0
- dbt/adapters/exceptions/database.py +51 -0
- dbt/adapters/factory.py +246 -0
- dbt/adapters/protocol.py +173 -0
- dbt/adapters/reference_keys.py +39 -0
- dbt/adapters/relation_configs/README.md +25 -0
- dbt/adapters/relation_configs/__init__.py +12 -0
- dbt/adapters/relation_configs/config_base.py +44 -0
- dbt/adapters/relation_configs/config_change.py +24 -0
- dbt/adapters/relation_configs/config_validation.py +57 -0
- dbt/adapters/sql/__init__.py +2 -0
- dbt/adapters/sql/connections.py +195 -0
- dbt/adapters/sql/impl.py +273 -0
- dbt/adapters/utils.py +69 -0
- dbt/include/global_project/__init__.py +4 -0
- dbt/include/global_project/dbt_project.yml +7 -0
- dbt/include/global_project/docs/overview.md +43 -0
- dbt/include/global_project/macros/adapters/apply_grants.sql +167 -0
- dbt/include/global_project/macros/adapters/columns.sql +137 -0
- dbt/include/global_project/macros/adapters/freshness.sql +16 -0
- dbt/include/global_project/macros/adapters/indexes.sql +41 -0
- dbt/include/global_project/macros/adapters/metadata.sql +96 -0
- dbt/include/global_project/macros/adapters/persist_docs.sql +33 -0
- dbt/include/global_project/macros/adapters/relation.sql +79 -0
- dbt/include/global_project/macros/adapters/schema.sql +20 -0
- dbt/include/global_project/macros/adapters/show.sql +22 -0
- dbt/include/global_project/macros/adapters/timestamps.sql +44 -0
- dbt/include/global_project/macros/adapters/validate_sql.sql +10 -0
- dbt/include/global_project/macros/etc/datetime.sql +62 -0
- dbt/include/global_project/macros/etc/statement.sql +52 -0
- dbt/include/global_project/macros/generic_test_sql/accepted_values.sql +27 -0
- dbt/include/global_project/macros/generic_test_sql/not_null.sql +9 -0
- dbt/include/global_project/macros/generic_test_sql/relationships.sql +23 -0
- dbt/include/global_project/macros/generic_test_sql/unique.sql +12 -0
- dbt/include/global_project/macros/get_custom_name/get_custom_alias.sql +36 -0
- dbt/include/global_project/macros/get_custom_name/get_custom_database.sql +32 -0
- dbt/include/global_project/macros/get_custom_name/get_custom_schema.sql +60 -0
- dbt/include/global_project/macros/materializations/configs.sql +21 -0
- dbt/include/global_project/macros/materializations/hooks.sql +35 -0
- dbt/include/global_project/macros/materializations/models/clone/can_clone_table.sql +7 -0
- dbt/include/global_project/macros/materializations/models/clone/clone.sql +67 -0
- dbt/include/global_project/macros/materializations/models/clone/create_or_replace_clone.sql +7 -0
- dbt/include/global_project/macros/materializations/models/incremental/column_helpers.sql +80 -0
- dbt/include/global_project/macros/materializations/models/incremental/incremental.sql +92 -0
- dbt/include/global_project/macros/materializations/models/incremental/is_incremental.sql +13 -0
- dbt/include/global_project/macros/materializations/models/incremental/merge.sql +131 -0
- dbt/include/global_project/macros/materializations/models/incremental/on_schema_change.sql +144 -0
- dbt/include/global_project/macros/materializations/models/incremental/strategies.sql +79 -0
- dbt/include/global_project/macros/materializations/models/materialized_view.sql +121 -0
- dbt/include/global_project/macros/materializations/models/table.sql +64 -0
- dbt/include/global_project/macros/materializations/models/view.sql +72 -0
- dbt/include/global_project/macros/materializations/seeds/helpers.sql +128 -0
- dbt/include/global_project/macros/materializations/seeds/seed.sql +60 -0
- dbt/include/global_project/macros/materializations/snapshots/helpers.sql +181 -0
- dbt/include/global_project/macros/materializations/snapshots/snapshot.sql +99 -0
- dbt/include/global_project/macros/materializations/snapshots/snapshot_merge.sql +25 -0
- dbt/include/global_project/macros/materializations/snapshots/strategies.sql +174 -0
- dbt/include/global_project/macros/materializations/tests/helpers.sql +14 -0
- dbt/include/global_project/macros/materializations/tests/test.sql +60 -0
- dbt/include/global_project/macros/materializations/tests/where_subquery.sql +15 -0
- dbt/include/global_project/macros/python_model/python.sql +103 -0
- dbt/include/global_project/macros/relations/column/columns_spec_ddl.sql +89 -0
- dbt/include/global_project/macros/relations/create.sql +23 -0
- dbt/include/global_project/macros/relations/create_backup.sql +17 -0
- dbt/include/global_project/macros/relations/create_intermediate.sql +17 -0
- dbt/include/global_project/macros/relations/drop.sql +41 -0
- dbt/include/global_project/macros/relations/drop_backup.sql +14 -0
- dbt/include/global_project/macros/relations/materialized_view/alter.sql +55 -0
- dbt/include/global_project/macros/relations/materialized_view/create.sql +10 -0
- dbt/include/global_project/macros/relations/materialized_view/drop.sql +14 -0
- dbt/include/global_project/macros/relations/materialized_view/refresh.sql +9 -0
- dbt/include/global_project/macros/relations/materialized_view/rename.sql +10 -0
- dbt/include/global_project/macros/relations/materialized_view/replace.sql +10 -0
- dbt/include/global_project/macros/relations/rename.sql +35 -0
- dbt/include/global_project/macros/relations/rename_intermediate.sql +14 -0
- dbt/include/global_project/macros/relations/replace.sql +50 -0
- dbt/include/global_project/macros/relations/schema.sql +8 -0
- dbt/include/global_project/macros/relations/table/create.sql +60 -0
- dbt/include/global_project/macros/relations/table/drop.sql +14 -0
- dbt/include/global_project/macros/relations/table/rename.sql +10 -0
- dbt/include/global_project/macros/relations/table/replace.sql +10 -0
- dbt/include/global_project/macros/relations/view/create.sql +27 -0
- dbt/include/global_project/macros/relations/view/drop.sql +14 -0
- dbt/include/global_project/macros/relations/view/rename.sql +10 -0
- dbt/include/global_project/macros/relations/view/replace.sql +66 -0
- dbt/include/global_project/macros/utils/any_value.sql +9 -0
- dbt/include/global_project/macros/utils/array_append.sql +8 -0
- dbt/include/global_project/macros/utils/array_concat.sql +7 -0
- dbt/include/global_project/macros/utils/array_construct.sql +12 -0
- dbt/include/global_project/macros/utils/bool_or.sql +9 -0
- dbt/include/global_project/macros/utils/cast_bool_to_text.sql +7 -0
- dbt/include/global_project/macros/utils/concat.sql +7 -0
- dbt/include/global_project/macros/utils/data_types.sql +129 -0
- dbt/include/global_project/macros/utils/date_spine.sql +75 -0
- dbt/include/global_project/macros/utils/date_trunc.sql +7 -0
- dbt/include/global_project/macros/utils/dateadd.sql +14 -0
- dbt/include/global_project/macros/utils/datediff.sql +14 -0
- dbt/include/global_project/macros/utils/escape_single_quotes.sql +8 -0
- dbt/include/global_project/macros/utils/except.sql +9 -0
- dbt/include/global_project/macros/utils/generate_series.sql +53 -0
- dbt/include/global_project/macros/utils/hash.sql +7 -0
- dbt/include/global_project/macros/utils/intersect.sql +9 -0
- dbt/include/global_project/macros/utils/last_day.sql +15 -0
- dbt/include/global_project/macros/utils/length.sql +11 -0
- dbt/include/global_project/macros/utils/listagg.sql +30 -0
- dbt/include/global_project/macros/utils/literal.sql +7 -0
- dbt/include/global_project/macros/utils/position.sql +11 -0
- dbt/include/global_project/macros/utils/replace.sql +14 -0
- dbt/include/global_project/macros/utils/right.sql +12 -0
- dbt/include/global_project/macros/utils/safe_cast.sql +9 -0
- dbt/include/global_project/macros/utils/split_part.sql +26 -0
- dbt/include/global_project/tests/generic/builtin.sql +30 -0
- dbt_adapters-0.1.0a1.dist-info/METADATA +81 -0
- dbt_adapters-0.1.0a1.dist-info/RECORD +147 -0
- dbt_adapters-0.1.0a1.dist-info/WHEEL +4 -0
- dbt_adapters-0.1.0a1.dist-info/licenses/LICENSE +201 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
{% macro get_columns_in_relation(relation) -%}
|
|
2
|
+
{{ return(adapter.dispatch('get_columns_in_relation', 'dbt')(relation)) }}
|
|
3
|
+
{% endmacro %}
|
|
4
|
+
|
|
5
|
+
{% macro default__get_columns_in_relation(relation) -%}
|
|
6
|
+
{{ exceptions.raise_not_implemented(
|
|
7
|
+
'get_columns_in_relation macro not implemented for adapter '+adapter.type()) }}
|
|
8
|
+
{% endmacro %}
|
|
9
|
+
|
|
10
|
+
{# helper for adapter-specific implementations of get_columns_in_relation #}
|
|
11
|
+
{% macro sql_convert_columns_in_relation(table) -%}
|
|
12
|
+
{% set columns = [] %}
|
|
13
|
+
{% for row in table %}
|
|
14
|
+
{% do columns.append(api.Column(*row)) %}
|
|
15
|
+
{% endfor %}
|
|
16
|
+
{{ return(columns) }}
|
|
17
|
+
{% endmacro %}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
{% macro get_empty_subquery_sql(select_sql, select_sql_header=none) -%}
|
|
21
|
+
{{ return(adapter.dispatch('get_empty_subquery_sql', 'dbt')(select_sql, select_sql_header)) }}
|
|
22
|
+
{% endmacro %}
|
|
23
|
+
|
|
24
|
+
{#
|
|
25
|
+
Builds a query that results in the same schema as the given select_sql statement, without necessitating a data scan.
|
|
26
|
+
Useful for running a query in a 'pre-flight' context, such as model contract enforcement (assert_columns_equivalent macro).
|
|
27
|
+
#}
|
|
28
|
+
{% macro default__get_empty_subquery_sql(select_sql, select_sql_header=none) %}
|
|
29
|
+
{%- if select_sql_header is not none -%}
|
|
30
|
+
{{ select_sql_header }}
|
|
31
|
+
{%- endif -%}
|
|
32
|
+
select * from (
|
|
33
|
+
{{ select_sql }}
|
|
34
|
+
) as __dbt_sbq
|
|
35
|
+
where false
|
|
36
|
+
limit 0
|
|
37
|
+
{% endmacro %}
|
|
38
|
+
|
|
39
|
+
{% macro get_empty_schema_sql(columns) -%}
|
|
40
|
+
{{ return(adapter.dispatch('get_empty_schema_sql', 'dbt')(columns)) }}
|
|
41
|
+
{% endmacro %}
|
|
42
|
+
|
|
43
|
+
{% macro default__get_empty_schema_sql(columns) %}
|
|
44
|
+
{%- set col_err = [] -%}
|
|
45
|
+
{%- set col_naked_numeric = [] -%}
|
|
46
|
+
select
|
|
47
|
+
{% for i in columns %}
|
|
48
|
+
{%- set col = columns[i] -%}
|
|
49
|
+
{%- if col['data_type'] is not defined -%}
|
|
50
|
+
{%- do col_err.append(col['name']) -%}
|
|
51
|
+
{#-- If this column's type is just 'numeric' then it is missing precision/scale, raise a warning --#}
|
|
52
|
+
{%- elif col['data_type'].strip().lower() in ('numeric', 'decimal', 'number') -%}
|
|
53
|
+
{%- do col_naked_numeric.append(col['name']) -%}
|
|
54
|
+
{%- endif -%}
|
|
55
|
+
{% set col_name = adapter.quote(col['name']) if col.get('quote') else col['name'] %}
|
|
56
|
+
cast(null as {{ col['data_type'] }}) as {{ col_name }}{{ ", " if not loop.last }}
|
|
57
|
+
{%- endfor -%}
|
|
58
|
+
{%- if (col_err | length) > 0 -%}
|
|
59
|
+
{{ exceptions.column_type_missing(column_names=col_err) }}
|
|
60
|
+
{%- elif (col_naked_numeric | length) > 0 -%}
|
|
61
|
+
{{ exceptions.warn("Detected columns with numeric type and unspecified precision/scale, this can lead to unintended rounding: " ~ col_naked_numeric ~ "`") }}
|
|
62
|
+
{%- endif -%}
|
|
63
|
+
{% endmacro %}
|
|
64
|
+
|
|
65
|
+
{% macro get_column_schema_from_query(select_sql, select_sql_header=none) -%}
|
|
66
|
+
{% set columns = [] %}
|
|
67
|
+
{# -- Using an 'empty subquery' here to get the same schema as the given select_sql statement, without necessitating a data scan.#}
|
|
68
|
+
{% set sql = get_empty_subquery_sql(select_sql, select_sql_header) %}
|
|
69
|
+
{% set column_schema = adapter.get_column_schema_from_query(sql) %}
|
|
70
|
+
{{ return(column_schema) }}
|
|
71
|
+
{% endmacro %}
|
|
72
|
+
|
|
73
|
+
-- here for back compat
|
|
74
|
+
{% macro get_columns_in_query(select_sql) -%}
|
|
75
|
+
{{ return(adapter.dispatch('get_columns_in_query', 'dbt')(select_sql)) }}
|
|
76
|
+
{% endmacro %}
|
|
77
|
+
|
|
78
|
+
{% macro default__get_columns_in_query(select_sql) %}
|
|
79
|
+
{% call statement('get_columns_in_query', fetch_result=True, auto_begin=False) -%}
|
|
80
|
+
{{ get_empty_subquery_sql(select_sql) }}
|
|
81
|
+
{% endcall %}
|
|
82
|
+
{{ return(load_result('get_columns_in_query').table.columns | map(attribute='name') | list) }}
|
|
83
|
+
{% endmacro %}
|
|
84
|
+
|
|
85
|
+
{% macro alter_column_type(relation, column_name, new_column_type) -%}
|
|
86
|
+
{{ return(adapter.dispatch('alter_column_type', 'dbt')(relation, column_name, new_column_type)) }}
|
|
87
|
+
{% endmacro %}
|
|
88
|
+
|
|
89
|
+
{% macro default__alter_column_type(relation, column_name, new_column_type) -%}
|
|
90
|
+
{#
|
|
91
|
+
1. Create a new column (w/ temp name and correct type)
|
|
92
|
+
2. Copy data over to it
|
|
93
|
+
3. Drop the existing column (cascade!)
|
|
94
|
+
4. Rename the new column to existing column
|
|
95
|
+
#}
|
|
96
|
+
{%- set tmp_column = column_name + "__dbt_alter" -%}
|
|
97
|
+
|
|
98
|
+
{% call statement('alter_column_type') %}
|
|
99
|
+
alter table {{ relation }} add column {{ adapter.quote(tmp_column) }} {{ new_column_type }};
|
|
100
|
+
update {{ relation }} set {{ adapter.quote(tmp_column) }} = {{ adapter.quote(column_name) }};
|
|
101
|
+
alter table {{ relation }} drop column {{ adapter.quote(column_name) }} cascade;
|
|
102
|
+
alter table {{ relation }} rename column {{ adapter.quote(tmp_column) }} to {{ adapter.quote(column_name) }}
|
|
103
|
+
{% endcall %}
|
|
104
|
+
|
|
105
|
+
{% endmacro %}
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
{% macro alter_relation_add_remove_columns(relation, add_columns = none, remove_columns = none) -%}
|
|
109
|
+
{{ return(adapter.dispatch('alter_relation_add_remove_columns', 'dbt')(relation, add_columns, remove_columns)) }}
|
|
110
|
+
{% endmacro %}
|
|
111
|
+
|
|
112
|
+
{% macro default__alter_relation_add_remove_columns(relation, add_columns, remove_columns) %}
|
|
113
|
+
|
|
114
|
+
{% if add_columns is none %}
|
|
115
|
+
{% set add_columns = [] %}
|
|
116
|
+
{% endif %}
|
|
117
|
+
{% if remove_columns is none %}
|
|
118
|
+
{% set remove_columns = [] %}
|
|
119
|
+
{% endif %}
|
|
120
|
+
|
|
121
|
+
{% set sql -%}
|
|
122
|
+
|
|
123
|
+
alter {{ relation.type }} {{ relation }}
|
|
124
|
+
|
|
125
|
+
{% for column in add_columns %}
|
|
126
|
+
add column {{ column.name }} {{ column.data_type }}{{ ',' if not loop.last }}
|
|
127
|
+
{% endfor %}{{ ',' if add_columns and remove_columns }}
|
|
128
|
+
|
|
129
|
+
{% for column in remove_columns %}
|
|
130
|
+
drop column {{ column.name }}{{ ',' if not loop.last }}
|
|
131
|
+
{% endfor %}
|
|
132
|
+
|
|
133
|
+
{%- endset -%}
|
|
134
|
+
|
|
135
|
+
{% do run_query(sql) %}
|
|
136
|
+
|
|
137
|
+
{% endmacro %}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{% macro collect_freshness(source, loaded_at_field, filter) %}
|
|
2
|
+
{{ return(adapter.dispatch('collect_freshness', 'dbt')(source, loaded_at_field, filter))}}
|
|
3
|
+
{% endmacro %}
|
|
4
|
+
|
|
5
|
+
{% macro default__collect_freshness(source, loaded_at_field, filter) %}
|
|
6
|
+
{% call statement('collect_freshness', fetch_result=True, auto_begin=False) -%}
|
|
7
|
+
select
|
|
8
|
+
max({{ loaded_at_field }}) as max_loaded_at,
|
|
9
|
+
{{ current_timestamp() }} as snapshotted_at
|
|
10
|
+
from {{ source }}
|
|
11
|
+
{% if filter %}
|
|
12
|
+
where {{ filter }}
|
|
13
|
+
{% endif %}
|
|
14
|
+
{% endcall %}
|
|
15
|
+
{{ return(load_result('collect_freshness')) }}
|
|
16
|
+
{% endmacro %}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{% macro get_create_index_sql(relation, index_dict) -%}
|
|
2
|
+
{{ return(adapter.dispatch('get_create_index_sql', 'dbt')(relation, index_dict)) }}
|
|
3
|
+
{% endmacro %}
|
|
4
|
+
|
|
5
|
+
{% macro default__get_create_index_sql(relation, index_dict) -%}
|
|
6
|
+
{% do return(None) %}
|
|
7
|
+
{% endmacro %}
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
{% macro create_indexes(relation) -%}
|
|
11
|
+
{{ adapter.dispatch('create_indexes', 'dbt')(relation) }}
|
|
12
|
+
{%- endmacro %}
|
|
13
|
+
|
|
14
|
+
{% macro default__create_indexes(relation) -%}
|
|
15
|
+
{%- set _indexes = config.get('indexes', default=[]) -%}
|
|
16
|
+
|
|
17
|
+
{% for _index_dict in _indexes %}
|
|
18
|
+
{% set create_index_sql = get_create_index_sql(relation, _index_dict) %}
|
|
19
|
+
{% if create_index_sql %}
|
|
20
|
+
{% do run_query(create_index_sql) %}
|
|
21
|
+
{% endif %}
|
|
22
|
+
{% endfor %}
|
|
23
|
+
{% endmacro %}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
{% macro get_drop_index_sql(relation, index_name) -%}
|
|
27
|
+
{{ adapter.dispatch('get_drop_index_sql', 'dbt')(relation, index_name) }}
|
|
28
|
+
{%- endmacro %}
|
|
29
|
+
|
|
30
|
+
{% macro default__get_drop_index_sql(relation, index_name) -%}
|
|
31
|
+
{{ exceptions.raise_compiler_error("`get_drop_index_sql has not been implemented for this adapter.") }}
|
|
32
|
+
{%- endmacro %}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
{% macro get_show_indexes_sql(relation) -%}
|
|
36
|
+
{{ adapter.dispatch('get_show_indexes_sql', 'dbt')(relation) }}
|
|
37
|
+
{%- endmacro %}
|
|
38
|
+
|
|
39
|
+
{% macro default__get_show_indexes_sql(relation) -%}
|
|
40
|
+
{{ exceptions.raise_compiler_error("`get_show_indexes_sql has not been implemented for this adapter.") }}
|
|
41
|
+
{%- endmacro %}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
{% macro get_catalog_relations(information_schema, relations) -%}
|
|
2
|
+
{{ return(adapter.dispatch('get_catalog_relations', 'dbt')(information_schema, relations)) }}
|
|
3
|
+
{%- endmacro %}
|
|
4
|
+
|
|
5
|
+
{% macro default__get_catalog_relations(information_schema, relations) -%}
|
|
6
|
+
{% set typename = adapter.type() %}
|
|
7
|
+
{% set msg -%}
|
|
8
|
+
get_catalog_relations not implemented for {{ typename }}
|
|
9
|
+
{%- endset %}
|
|
10
|
+
|
|
11
|
+
{{ exceptions.raise_compiler_error(msg) }}
|
|
12
|
+
{%- endmacro %}
|
|
13
|
+
|
|
14
|
+
{% macro get_catalog(information_schema, schemas) -%}
|
|
15
|
+
{{ return(adapter.dispatch('get_catalog', 'dbt')(information_schema, schemas)) }}
|
|
16
|
+
{%- endmacro %}
|
|
17
|
+
|
|
18
|
+
{% macro default__get_catalog(information_schema, schemas) -%}
|
|
19
|
+
|
|
20
|
+
{% set typename = adapter.type() %}
|
|
21
|
+
{% set msg -%}
|
|
22
|
+
get_catalog not implemented for {{ typename }}
|
|
23
|
+
{%- endset %}
|
|
24
|
+
|
|
25
|
+
{{ exceptions.raise_compiler_error(msg) }}
|
|
26
|
+
{% endmacro %}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
{% macro information_schema_name(database) %}
|
|
30
|
+
{{ return(adapter.dispatch('information_schema_name', 'dbt')(database)) }}
|
|
31
|
+
{% endmacro %}
|
|
32
|
+
|
|
33
|
+
{% macro default__information_schema_name(database) -%}
|
|
34
|
+
{%- if database -%}
|
|
35
|
+
{{ database }}.INFORMATION_SCHEMA
|
|
36
|
+
{%- else -%}
|
|
37
|
+
INFORMATION_SCHEMA
|
|
38
|
+
{%- endif -%}
|
|
39
|
+
{%- endmacro %}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
{% macro list_schemas(database) -%}
|
|
43
|
+
{{ return(adapter.dispatch('list_schemas', 'dbt')(database)) }}
|
|
44
|
+
{% endmacro %}
|
|
45
|
+
|
|
46
|
+
{% macro default__list_schemas(database) -%}
|
|
47
|
+
{% set sql %}
|
|
48
|
+
select distinct schema_name
|
|
49
|
+
from {{ information_schema_name(database) }}.SCHEMATA
|
|
50
|
+
where catalog_name ilike '{{ database }}'
|
|
51
|
+
{% endset %}
|
|
52
|
+
{{ return(run_query(sql)) }}
|
|
53
|
+
{% endmacro %}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
{% macro check_schema_exists(information_schema, schema) -%}
|
|
57
|
+
{{ return(adapter.dispatch('check_schema_exists', 'dbt')(information_schema, schema)) }}
|
|
58
|
+
{% endmacro %}
|
|
59
|
+
|
|
60
|
+
{% macro default__check_schema_exists(information_schema, schema) -%}
|
|
61
|
+
{% set sql -%}
|
|
62
|
+
select count(*)
|
|
63
|
+
from {{ information_schema.replace(information_schema_view='SCHEMATA') }}
|
|
64
|
+
where catalog_name='{{ information_schema.database }}'
|
|
65
|
+
and schema_name='{{ schema }}'
|
|
66
|
+
{%- endset %}
|
|
67
|
+
{{ return(run_query(sql)) }}
|
|
68
|
+
{% endmacro %}
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
{% macro list_relations_without_caching(schema_relation) %}
|
|
72
|
+
{{ return(adapter.dispatch('list_relations_without_caching', 'dbt')(schema_relation)) }}
|
|
73
|
+
{% endmacro %}
|
|
74
|
+
|
|
75
|
+
{% macro default__list_relations_without_caching(schema_relation) %}
|
|
76
|
+
{{ exceptions.raise_not_implemented(
|
|
77
|
+
'list_relations_without_caching macro not implemented for adapter '+adapter.type()) }}
|
|
78
|
+
{% endmacro %}
|
|
79
|
+
|
|
80
|
+
{% macro get_relations() %}
|
|
81
|
+
{{ return(adapter.dispatch('get_relations', 'dbt')()) }}
|
|
82
|
+
{% endmacro %}
|
|
83
|
+
|
|
84
|
+
{% macro default__get_relations() %}
|
|
85
|
+
{{ exceptions.raise_not_implemented(
|
|
86
|
+
'get_relations macro not implemented for adapter '+adapter.type()) }}
|
|
87
|
+
{% endmacro %}
|
|
88
|
+
|
|
89
|
+
{% macro get_relation_last_modified(information_schema, relations) %}
|
|
90
|
+
{{ return(adapter.dispatch('get_relation_last_modified', 'dbt')(information_schema, relations)) }}
|
|
91
|
+
{% endmacro %}
|
|
92
|
+
|
|
93
|
+
{% macro default__get_relation_last_modified(information_schema, relations) %}
|
|
94
|
+
{{ exceptions.raise_not_implemented(
|
|
95
|
+
'get_relation_last_modified macro not implemented for adapter ' + adapter.type()) }}
|
|
96
|
+
{% endmacro %}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{% macro alter_column_comment(relation, column_dict) -%}
|
|
2
|
+
{{ return(adapter.dispatch('alter_column_comment', 'dbt')(relation, column_dict)) }}
|
|
3
|
+
{% endmacro %}
|
|
4
|
+
|
|
5
|
+
{% macro default__alter_column_comment(relation, column_dict) -%}
|
|
6
|
+
{{ exceptions.raise_not_implemented(
|
|
7
|
+
'alter_column_comment macro not implemented for adapter '+adapter.type()) }}
|
|
8
|
+
{% endmacro %}
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
{% macro alter_relation_comment(relation, relation_comment) -%}
|
|
12
|
+
{{ return(adapter.dispatch('alter_relation_comment', 'dbt')(relation, relation_comment)) }}
|
|
13
|
+
{% endmacro %}
|
|
14
|
+
|
|
15
|
+
{% macro default__alter_relation_comment(relation, relation_comment) -%}
|
|
16
|
+
{{ exceptions.raise_not_implemented(
|
|
17
|
+
'alter_relation_comment macro not implemented for adapter '+adapter.type()) }}
|
|
18
|
+
{% endmacro %}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
{% macro persist_docs(relation, model, for_relation=true, for_columns=true) -%}
|
|
22
|
+
{{ return(adapter.dispatch('persist_docs', 'dbt')(relation, model, for_relation, for_columns)) }}
|
|
23
|
+
{% endmacro %}
|
|
24
|
+
|
|
25
|
+
{% macro default__persist_docs(relation, model, for_relation, for_columns) -%}
|
|
26
|
+
{% if for_relation and config.persist_relation_docs() and model.description %}
|
|
27
|
+
{% do run_query(alter_relation_comment(relation, model.description)) %}
|
|
28
|
+
{% endif %}
|
|
29
|
+
|
|
30
|
+
{% if for_columns and config.persist_column_docs() and model.columns %}
|
|
31
|
+
{% do run_query(alter_column_comment(relation, model.columns)) %}
|
|
32
|
+
{% endif %}
|
|
33
|
+
{% endmacro %}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{% macro make_intermediate_relation(base_relation, suffix='__dbt_tmp') %}
|
|
2
|
+
{{ return(adapter.dispatch('make_intermediate_relation', 'dbt')(base_relation, suffix)) }}
|
|
3
|
+
{% endmacro %}
|
|
4
|
+
|
|
5
|
+
{% macro default__make_intermediate_relation(base_relation, suffix) %}
|
|
6
|
+
{{ return(default__make_temp_relation(base_relation, suffix)) }}
|
|
7
|
+
{% endmacro %}
|
|
8
|
+
|
|
9
|
+
{% macro make_temp_relation(base_relation, suffix='__dbt_tmp') %}
|
|
10
|
+
{{ return(adapter.dispatch('make_temp_relation', 'dbt')(base_relation, suffix)) }}
|
|
11
|
+
{% endmacro %}
|
|
12
|
+
|
|
13
|
+
{% macro default__make_temp_relation(base_relation, suffix) %}
|
|
14
|
+
{%- set temp_identifier = base_relation.identifier ~ suffix -%}
|
|
15
|
+
{%- set temp_relation = base_relation.incorporate(
|
|
16
|
+
path={"identifier": temp_identifier}) -%}
|
|
17
|
+
|
|
18
|
+
{{ return(temp_relation) }}
|
|
19
|
+
{% endmacro %}
|
|
20
|
+
|
|
21
|
+
{% macro make_backup_relation(base_relation, backup_relation_type, suffix='__dbt_backup') %}
|
|
22
|
+
{{ return(adapter.dispatch('make_backup_relation', 'dbt')(base_relation, backup_relation_type, suffix)) }}
|
|
23
|
+
{% endmacro %}
|
|
24
|
+
|
|
25
|
+
{% macro default__make_backup_relation(base_relation, backup_relation_type, suffix) %}
|
|
26
|
+
{%- set backup_identifier = base_relation.identifier ~ suffix -%}
|
|
27
|
+
{%- set backup_relation = base_relation.incorporate(
|
|
28
|
+
path={"identifier": backup_identifier},
|
|
29
|
+
type=backup_relation_type
|
|
30
|
+
) -%}
|
|
31
|
+
{{ return(backup_relation) }}
|
|
32
|
+
{% endmacro %}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
{% macro truncate_relation(relation) -%}
|
|
36
|
+
{{ return(adapter.dispatch('truncate_relation', 'dbt')(relation)) }}
|
|
37
|
+
{% endmacro %}
|
|
38
|
+
|
|
39
|
+
{% macro default__truncate_relation(relation) -%}
|
|
40
|
+
{% call statement('truncate_relation') -%}
|
|
41
|
+
truncate table {{ relation }}
|
|
42
|
+
{%- endcall %}
|
|
43
|
+
{% endmacro %}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
{% macro get_or_create_relation(database, schema, identifier, type) -%}
|
|
47
|
+
{{ return(adapter.dispatch('get_or_create_relation', 'dbt')(database, schema, identifier, type)) }}
|
|
48
|
+
{% endmacro %}
|
|
49
|
+
|
|
50
|
+
{% macro default__get_or_create_relation(database, schema, identifier, type) %}
|
|
51
|
+
{%- set target_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) %}
|
|
52
|
+
|
|
53
|
+
{% if target_relation %}
|
|
54
|
+
{% do return([true, target_relation]) %}
|
|
55
|
+
{% endif %}
|
|
56
|
+
|
|
57
|
+
{%- set new_relation = api.Relation.create(
|
|
58
|
+
database=database,
|
|
59
|
+
schema=schema,
|
|
60
|
+
identifier=identifier,
|
|
61
|
+
type=type
|
|
62
|
+
) -%}
|
|
63
|
+
{% do return([false, new_relation]) %}
|
|
64
|
+
{% endmacro %}
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
-- a user-friendly interface into adapter.get_relation
|
|
68
|
+
{% macro load_cached_relation(relation) %}
|
|
69
|
+
{% do return(adapter.get_relation(
|
|
70
|
+
database=relation.database,
|
|
71
|
+
schema=relation.schema,
|
|
72
|
+
identifier=relation.identifier
|
|
73
|
+
)) -%}
|
|
74
|
+
{% endmacro %}
|
|
75
|
+
|
|
76
|
+
-- old name for backwards compatibility
|
|
77
|
+
{% macro load_relation(relation) %}
|
|
78
|
+
{{ return(load_cached_relation(relation)) }}
|
|
79
|
+
{% endmacro %}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{% macro create_schema(relation) -%}
|
|
2
|
+
{{ adapter.dispatch('create_schema', 'dbt')(relation) }}
|
|
3
|
+
{% endmacro %}
|
|
4
|
+
|
|
5
|
+
{% macro default__create_schema(relation) -%}
|
|
6
|
+
{%- call statement('create_schema') -%}
|
|
7
|
+
create schema if not exists {{ relation.without_identifier() }}
|
|
8
|
+
{% endcall %}
|
|
9
|
+
{% endmacro %}
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
{% macro drop_schema(relation) -%}
|
|
13
|
+
{{ adapter.dispatch('drop_schema', 'dbt')(relation) }}
|
|
14
|
+
{% endmacro %}
|
|
15
|
+
|
|
16
|
+
{% macro default__drop_schema(relation) -%}
|
|
17
|
+
{%- call statement('drop_schema') -%}
|
|
18
|
+
drop schema if exists {{ relation.without_identifier() }} cascade
|
|
19
|
+
{% endcall %}
|
|
20
|
+
{% endmacro %}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{% macro get_show_sql(compiled_code, sql_header, limit) -%}
|
|
2
|
+
{%- if sql_header -%}
|
|
3
|
+
{{ sql_header }}
|
|
4
|
+
{%- endif -%}
|
|
5
|
+
{%- if limit is not none -%}
|
|
6
|
+
{{ get_limit_subquery_sql(compiled_code, limit) }}
|
|
7
|
+
{%- else -%}
|
|
8
|
+
{{ compiled_code }}
|
|
9
|
+
{%- endif -%}
|
|
10
|
+
{% endmacro %}
|
|
11
|
+
|
|
12
|
+
{% macro get_limit_subquery_sql(sql, limit) %}
|
|
13
|
+
{{ adapter.dispatch('get_limit_subquery_sql', 'dbt')(sql, limit) }}
|
|
14
|
+
{% endmacro %}
|
|
15
|
+
|
|
16
|
+
{% macro default__get_limit_subquery_sql(sql, limit) %}
|
|
17
|
+
select *
|
|
18
|
+
from (
|
|
19
|
+
{{ sql }}
|
|
20
|
+
) as model_limit_subq
|
|
21
|
+
limit {{ limit }}
|
|
22
|
+
{% endmacro %}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{%- macro current_timestamp() -%}
|
|
2
|
+
{{ adapter.dispatch('current_timestamp', 'dbt')() }}
|
|
3
|
+
{%- endmacro -%}
|
|
4
|
+
|
|
5
|
+
{% macro default__current_timestamp() -%}
|
|
6
|
+
{{ exceptions.raise_not_implemented(
|
|
7
|
+
'current_timestamp macro not implemented for adapter ' + adapter.type()) }}
|
|
8
|
+
{%- endmacro %}
|
|
9
|
+
|
|
10
|
+
{%- macro snapshot_get_time() -%}
|
|
11
|
+
{{ adapter.dispatch('snapshot_get_time', 'dbt')() }}
|
|
12
|
+
{%- endmacro -%}
|
|
13
|
+
|
|
14
|
+
{% macro default__snapshot_get_time() %}
|
|
15
|
+
{{ current_timestamp() }}
|
|
16
|
+
{% endmacro %}
|
|
17
|
+
|
|
18
|
+
---------------------------------------------
|
|
19
|
+
|
|
20
|
+
/* {#
|
|
21
|
+
DEPRECATED: DO NOT USE IN NEW PROJECTS
|
|
22
|
+
|
|
23
|
+
This is ONLY to handle the fact that Snowflake + Postgres had functionally
|
|
24
|
+
different implementations of {{ dbt.current_timestamp }} + {{ dbt_utils.current_timestamp }}
|
|
25
|
+
|
|
26
|
+
If you had a project or package that called {{ dbt_utils.current_timestamp() }}, you should
|
|
27
|
+
continue to use this macro to guarantee identical behavior on those two databases.
|
|
28
|
+
#} */
|
|
29
|
+
|
|
30
|
+
{% macro current_timestamp_backcompat() %}
|
|
31
|
+
{{ return(adapter.dispatch('current_timestamp_backcompat', 'dbt')()) }}
|
|
32
|
+
{% endmacro %}
|
|
33
|
+
|
|
34
|
+
{% macro default__current_timestamp_backcompat() %}
|
|
35
|
+
current_timestamp::timestamp
|
|
36
|
+
{% endmacro %}
|
|
37
|
+
|
|
38
|
+
{% macro current_timestamp_in_utc_backcompat() %}
|
|
39
|
+
{{ return(adapter.dispatch('current_timestamp_in_utc_backcompat', 'dbt')()) }}
|
|
40
|
+
{% endmacro %}
|
|
41
|
+
|
|
42
|
+
{% macro default__current_timestamp_in_utc_backcompat() %}
|
|
43
|
+
{{ return(adapter.dispatch('current_timestamp_backcompat', 'dbt')()) }}
|
|
44
|
+
{% endmacro %}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{% macro validate_sql(sql) -%}
|
|
2
|
+
{{ return(adapter.dispatch('validate_sql', 'dbt')(sql)) }}
|
|
3
|
+
{% endmacro %}
|
|
4
|
+
|
|
5
|
+
{% macro default__validate_sql(sql) -%}
|
|
6
|
+
{% call statement('validate_sql') -%}
|
|
7
|
+
explain {{ sql }}
|
|
8
|
+
{% endcall %}
|
|
9
|
+
{{ return(load_result('validate_sql')) }}
|
|
10
|
+
{% endmacro %}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{% macro convert_datetime(date_str, date_fmt) %}
|
|
2
|
+
|
|
3
|
+
{% set error_msg -%}
|
|
4
|
+
The provided partition date '{{ date_str }}' does not match the expected format '{{ date_fmt }}'
|
|
5
|
+
{%- endset %}
|
|
6
|
+
|
|
7
|
+
{% set res = try_or_compiler_error(error_msg, modules.datetime.datetime.strptime, date_str.strip(), date_fmt) %}
|
|
8
|
+
{{ return(res) }}
|
|
9
|
+
|
|
10
|
+
{% endmacro %}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
{% macro dates_in_range(start_date_str, end_date_str=none, in_fmt="%Y%m%d", out_fmt="%Y%m%d") %}
|
|
14
|
+
{% set end_date_str = start_date_str if end_date_str is none else end_date_str %}
|
|
15
|
+
|
|
16
|
+
{% set start_date = convert_datetime(start_date_str, in_fmt) %}
|
|
17
|
+
{% set end_date = convert_datetime(end_date_str, in_fmt) %}
|
|
18
|
+
|
|
19
|
+
{% set day_count = (end_date - start_date).days %}
|
|
20
|
+
{% if day_count < 0 %}
|
|
21
|
+
{% set msg -%}
|
|
22
|
+
Partition start date is after the end date ({{ start_date }}, {{ end_date }})
|
|
23
|
+
{%- endset %}
|
|
24
|
+
|
|
25
|
+
{{ exceptions.raise_compiler_error(msg, model) }}
|
|
26
|
+
{% endif %}
|
|
27
|
+
|
|
28
|
+
{% set date_list = [] %}
|
|
29
|
+
{% for i in range(0, day_count + 1) %}
|
|
30
|
+
{% set the_date = (modules.datetime.timedelta(days=i) + start_date) %}
|
|
31
|
+
{% if not out_fmt %}
|
|
32
|
+
{% set _ = date_list.append(the_date) %}
|
|
33
|
+
{% else %}
|
|
34
|
+
{% set _ = date_list.append(the_date.strftime(out_fmt)) %}
|
|
35
|
+
{% endif %}
|
|
36
|
+
{% endfor %}
|
|
37
|
+
|
|
38
|
+
{{ return(date_list) }}
|
|
39
|
+
{% endmacro %}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
{% macro partition_range(raw_partition_date, date_fmt='%Y%m%d') %}
|
|
43
|
+
{% set partition_range = (raw_partition_date | string).split(",") %}
|
|
44
|
+
|
|
45
|
+
{% if (partition_range | length) == 1 %}
|
|
46
|
+
{% set start_date = partition_range[0] %}
|
|
47
|
+
{% set end_date = none %}
|
|
48
|
+
{% elif (partition_range | length) == 2 %}
|
|
49
|
+
{% set start_date = partition_range[0] %}
|
|
50
|
+
{% set end_date = partition_range[1] %}
|
|
51
|
+
{% else %}
|
|
52
|
+
{{ exceptions.raise_compiler_error("Invalid partition time. Expected format: {Start Date}[,{End Date}]. Got: " ~ raw_partition_date) }}
|
|
53
|
+
{% endif %}
|
|
54
|
+
|
|
55
|
+
{{ return(dates_in_range(start_date, end_date, in_fmt=date_fmt)) }}
|
|
56
|
+
{% endmacro %}
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
{% macro py_current_timestring() %}
|
|
60
|
+
{% set dt = modules.datetime.datetime.now() %}
|
|
61
|
+
{% do return(dt.strftime("%Y%m%d%H%M%S%f")) %}
|
|
62
|
+
{% endmacro %}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{#--
|
|
2
|
+
The macro override naming method (spark__statement) only works for macros which are called with adapter.dispatch. For macros called directly, you can just redefine them.
|
|
3
|
+
--#}
|
|
4
|
+
{%- macro statement(name=None, fetch_result=False, auto_begin=True, language='sql') -%}
|
|
5
|
+
{%- if execute: -%}
|
|
6
|
+
{%- set compiled_code = caller() -%}
|
|
7
|
+
|
|
8
|
+
{%- if name == 'main' -%}
|
|
9
|
+
{{ log('Writing runtime {} for node "{}"'.format(language, model['unique_id'])) }}
|
|
10
|
+
{{ write(compiled_code) }}
|
|
11
|
+
{%- endif -%}
|
|
12
|
+
{%- if language == 'sql'-%}
|
|
13
|
+
{%- set res, table = adapter.execute(compiled_code, auto_begin=auto_begin, fetch=fetch_result) -%}
|
|
14
|
+
{%- elif language == 'python' -%}
|
|
15
|
+
{%- set res = submit_python_job(model, compiled_code) -%}
|
|
16
|
+
{#-- TODO: What should table be for python models? --#}
|
|
17
|
+
{%- set table = None -%}
|
|
18
|
+
{%- else -%}
|
|
19
|
+
{% do exceptions.raise_compiler_error("statement macro didn't get supported language") %}
|
|
20
|
+
{%- endif -%}
|
|
21
|
+
|
|
22
|
+
{%- if name is not none -%}
|
|
23
|
+
{{ store_result(name, response=res, agate_table=table) }}
|
|
24
|
+
{%- endif -%}
|
|
25
|
+
|
|
26
|
+
{%- endif -%}
|
|
27
|
+
{%- endmacro %}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
{% macro noop_statement(name=None, message=None, code=None, rows_affected=None, res=None) -%}
|
|
31
|
+
{%- set sql = caller() -%}
|
|
32
|
+
|
|
33
|
+
{%- if name == 'main' -%}
|
|
34
|
+
{{ log('Writing runtime SQL for node "{}"'.format(model['unique_id'])) }}
|
|
35
|
+
{{ write(sql) }}
|
|
36
|
+
{%- endif -%}
|
|
37
|
+
|
|
38
|
+
{%- if name is not none -%}
|
|
39
|
+
{{ store_raw_result(name, message=message, code=code, rows_affected=rows_affected, agate_table=res) }}
|
|
40
|
+
{%- endif -%}
|
|
41
|
+
|
|
42
|
+
{%- endmacro %}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
{# a user-friendly interface into statements #}
|
|
46
|
+
{% macro run_query(sql) %}
|
|
47
|
+
{% call statement("run_query_statement", fetch_result=true, auto_begin=false) %}
|
|
48
|
+
{{ sql }}
|
|
49
|
+
{% endcall %}
|
|
50
|
+
|
|
51
|
+
{% do return(load_result("run_query_statement").table) %}
|
|
52
|
+
{% endmacro %}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{% macro default__test_accepted_values(model, column_name, values, quote=True) %}
|
|
2
|
+
|
|
3
|
+
with all_values as (
|
|
4
|
+
|
|
5
|
+
select
|
|
6
|
+
{{ column_name }} as value_field,
|
|
7
|
+
count(*) as n_records
|
|
8
|
+
|
|
9
|
+
from {{ model }}
|
|
10
|
+
group by {{ column_name }}
|
|
11
|
+
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
select *
|
|
15
|
+
from all_values
|
|
16
|
+
where value_field not in (
|
|
17
|
+
{% for value in values -%}
|
|
18
|
+
{% if quote -%}
|
|
19
|
+
'{{ value }}'
|
|
20
|
+
{%- else -%}
|
|
21
|
+
{{ value }}
|
|
22
|
+
{%- endif -%}
|
|
23
|
+
{%- if not loop.last -%},{%- endif %}
|
|
24
|
+
{%- endfor %}
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
{% endmacro %}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{% macro default__test_relationships(model, column_name, to, field) %}
|
|
2
|
+
|
|
3
|
+
with child as (
|
|
4
|
+
select {{ column_name }} as from_field
|
|
5
|
+
from {{ model }}
|
|
6
|
+
where {{ column_name }} is not null
|
|
7
|
+
),
|
|
8
|
+
|
|
9
|
+
parent as (
|
|
10
|
+
select {{ field }} as to_field
|
|
11
|
+
from {{ to }}
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
select
|
|
15
|
+
from_field
|
|
16
|
+
|
|
17
|
+
from child
|
|
18
|
+
left join parent
|
|
19
|
+
on child.from_field = parent.to_field
|
|
20
|
+
|
|
21
|
+
where parent.to_field is null
|
|
22
|
+
|
|
23
|
+
{% endmacro %}
|