-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added macro to show how contracts work in samples/model_governance fo…
…lder
- Loading branch information
Faith Lierheimer
committed
Jul 24, 2024
1 parent
b8a5c18
commit b7bc28a
Showing
1 changed file
with
91 additions
and
0 deletions.
There are no files selected for viewing
91 changes: 91 additions & 0 deletions
91
models/_samples/model_governance/how_contracts_work_columns_spec_ddl.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
--this is the macro dbt uses under the hood to enforce contracts. as-is in this | ||
-- project, it does not affect anything. it's here for display only. | ||
{%- macro get_table_columns_and_constraints() -%} | ||
{{ adapter.dispatch('get_table_columns_and_constraints', 'dbt')() }} | ||
{%- endmacro -%} | ||
|
||
{% macro default__get_table_columns_and_constraints() -%} | ||
{{ return(table_columns_and_constraints()) }} | ||
{%- endmacro %} | ||
|
||
{% macro table_columns_and_constraints() %} | ||
{# loop through user_provided_columns to create DDL with data types and constraints #} | ||
{%- set raw_column_constraints = adapter.render_raw_columns_constraints(raw_columns=model['columns']) -%} | ||
{%- set raw_model_constraints = adapter.render_raw_model_constraints(raw_constraints=model['constraints']) -%} | ||
( | ||
{% for c in raw_column_constraints -%} | ||
{{ c }}{{ "," if not loop.last or raw_model_constraints }} | ||
{% endfor %} | ||
{% for c in raw_model_constraints -%} | ||
{{ c }}{{ "," if not loop.last }} | ||
{% endfor -%} | ||
) | ||
{% endmacro %} | ||
|
||
{%- macro get_assert_columns_equivalent(sql) -%} | ||
{{ adapter.dispatch('get_assert_columns_equivalent', 'dbt')(sql) }} | ||
{%- endmacro -%} | ||
|
||
{% macro default__get_assert_columns_equivalent(sql) -%} | ||
{{ return(assert_columns_equivalent(sql)) }} | ||
{%- endmacro %} | ||
|
||
{# | ||
Compares the column schema provided by a model's sql file to the column schema provided by a model's schema file. | ||
If any differences in name, data_type or number of columns exist between the two schemas, raises a compiler error | ||
#} | ||
{% macro assert_columns_equivalent(sql) %} | ||
|
||
{#-- First ensure the user has defined 'columns' in yaml specification --#} | ||
{%- set user_defined_columns = model['columns'] -%} | ||
{%- if not user_defined_columns -%} | ||
{{ exceptions.raise_contract_error([], []) }} | ||
{%- endif -%} | ||
|
||
{#-- Obtain the column schema provided by sql file. #} | ||
{%- set sql_file_provided_columns = get_column_schema_from_query(sql, config.get('sql_header', none)) -%} | ||
{#--Obtain the column schema provided by the schema file by generating an 'empty schema' query from the model's columns. #} | ||
{%- set schema_file_provided_columns = get_column_schema_from_query(get_empty_schema_sql(user_defined_columns)) -%} | ||
|
||
{#-- create dictionaries with name and formatted data type and strings for exception #} | ||
{%- set sql_columns = format_columns(sql_file_provided_columns) -%} | ||
{%- set yaml_columns = format_columns(schema_file_provided_columns) -%} | ||
|
||
{%- if sql_columns|length != yaml_columns|length -%} | ||
{%- do exceptions.raise_contract_error(yaml_columns, sql_columns) -%} | ||
{%- endif -%} | ||
|
||
{%- for sql_col in sql_columns -%} | ||
{%- set yaml_col = [] -%} | ||
{%- for this_col in yaml_columns -%} | ||
{%- if this_col['name'] == sql_col['name'] -%} | ||
{%- do yaml_col.append(this_col) -%} | ||
{%- break -%} | ||
{%- endif -%} | ||
{%- endfor -%} | ||
{%- if not yaml_col -%} | ||
{#-- Column with name not found in yaml #} | ||
{%- do exceptions.raise_contract_error(yaml_columns, sql_columns) -%} | ||
{%- endif -%} | ||
{%- if sql_col['formatted'] != yaml_col[0]['formatted'] -%} | ||
{#-- Column data types don't match #} | ||
{%- do exceptions.raise_contract_error(yaml_columns, sql_columns) -%} | ||
{%- endif -%} | ||
{%- endfor -%} | ||
|
||
{% endmacro %} | ||
|
||
{% macro format_columns(columns) %} | ||
{% set formatted_columns = [] %} | ||
{% for column in columns %} | ||
{%- set formatted_column = adapter.dispatch('format_column', 'dbt')(column) -%} | ||
{%- do formatted_columns.append(formatted_column) -%} | ||
{% endfor %} | ||
{{ return(formatted_columns) }} | ||
{% endmacro %} | ||
|
||
{% macro default__format_column(column) -%} | ||
{% set data_type = column.dtype %} | ||
{% set formatted = column.column.lower() ~ " " ~ data_type %} | ||
{{ return({'name': column.name, 'data_type': data_type, 'formatted': formatted}) }} | ||
{%- endmacro -%} |