{% macro string_mapping(table_name, primary_key, run_mode=none) -%} {{ return(adapter.dispatch('string_mapping', 'dynamics_365_crm')(table_name, primary_key, run_mode)) }} {% endmacro %} {% macro default__string_mapping(table_name, primary_key, run_mode=none) %} {{ config(enabled=var('dynamics_365_crm_using_' ~ table_name, True)) }} {% if run_mode is not none %} {% do exceptions.warn("The `run_mode` argument in `string_mapping` is deprecated and no longer has any effect. It will be removed in a future release.") if execute %} {% endif %} {%- set columns = adapter.get_columns_in_relation(source('dynamics_365_crm', table_name)) -%} {# Retrieves the attribute names available for the subject table #} {%- set stringmap_columns = adapter.get_columns_in_relation(source('dynamics_365_crm', 'stringmap')) | map(attribute='name') | map('lower') | list -%} {%- set attribute_column = 'renamed_attributename' if 'renamed_attributename' in stringmap_columns else 'attributename' -%} {%- set attributes = dbt_utils.get_column_values( table=source('dynamics_365_crm', 'stringmap'), where="lower(objecttypecode) = '" ~ table_name ~ "'", column=attribute_column) -%} {# Create two lists: 1. fields for mapping 2. all the remaining fields #} {%- set fields = [] -%} {%- set non_pivot_fields = [] -%} {%- for col in columns -%} {%- set data_type = col.data_type|lower %} {# For Databricks, we use partial string matches since col.is_number() doesn't work as expected. We want partial matches to catch types like int2, int4, bigint, float4, double precision, etc. #} {%- set is_number = ('int' in data_type or 'float' in data_type or 'numeric' in data_type or 'decimal' in data_type or 'serial' in data_type or 'real' in data_type or 'double' in data_type ) if target.type == 'databricks' else col.is_number() -%} {%- if col.name | lower in attributes | map('lower') and is_number -%} {%- do fields.append(col.name) -%} {%- else -%} {%- do non_pivot_fields.append(col.name) -%} {%- endif -%} {%- endfor -%} {# Only pivot/unpivot if there's at least one column to map. Otherwise pass the source through unchanged #} {% if fields | length > 0 %} with base as( select * from {{ source('dynamics_365_crm', table_name) }} -- Select only the primary key to shorten the compiled query--rejoin remaining fields later ), unpivoted as ( {%- for field in fields -%} select {{ primary_key }}, cast('{{ field }}' as {{ dbt.type_string() }}) as fieldname, cast({{ field }} as {{ dbt.type_int() }}) as fieldvalue from base {{ 'union all' if not loop.last }} {% endfor %} ), stringmaps as ( select stringmapid, cast(attributevalue as {{ dbt.type_int() }}) as attributevalue, cast({{ attribute_column }} as {{ dbt.type_string() }}) as attributename, cast(objecttypecode as {{ dbt.type_string() }}) as objecttypecode, cast(value as {{ dbt.type_string()}}) as stringmap_value from {{ source('dynamics_365_crm', 'stringmap')}} where lower(objecttypecode) = {{ "'" ~ table_name ~ "'" }} and not coalesce(_fivetran_deleted, false) ), joined as ( -- the long format table can easily be joined with the stringmap table select unpivoted.*, stringmaps.stringmap_value as fieldvalue_name from unpivoted left join stringmaps on lower(unpivoted.fieldname) = lower(stringmaps.attributename) and unpivoted.fieldvalue = stringmaps.attributevalue ), repivoted as ( -- convert back to wide format, now with the human readable columns select {% for non_pivot_field in non_pivot_fields -%} base.{{ non_pivot_field }}, {% endfor %} {% for field in fields -%} max(case when lower(joined.fieldname) = lower('{{ field }}') then joined.fieldvalue else null end) as {{ field }}, max(case when lower(joined.fieldname) = lower('{{ field }}') then joined.fieldvalue_name else null end) as {{ field }}_label{{ ',' if not loop.last }} {% endfor %} from joined left join base on joined.{{ primary_key }} = base.{{ primary_key }} {{ dbt_utils.group_by(non_pivot_fields | length) }} ) select * from repivoted {%- else %} {# When no columns to string map, pass the source through unchanged #} select * from {{ source('dynamics_365_crm', table_name) }} {% endif %} {% endmacro %}