From f6a36529a29d06dc2ced51779e334512af43e86f Mon Sep 17 00:00:00 2001 From: Celine Verhoef Date: Wed, 4 Sep 2024 13:15:01 +0200 Subject: [PATCH] feat: add json macro --- README.md | 7 +++++++ dbt_project.yml | 2 +- integration_tests/models/schema.yml | 9 +++++++++ integration_tests/models/test_json.sql | 16 ++++++++++++++++ macros/string_functions/json.sql | 9 +++++++++ 5 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 integration_tests/models/test_json.sql create mode 100644 macros/string_functions/json.sql diff --git a/README.md b/README.md index 877969a..4cbf823 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ This dbt package contains macros for SQL functions to run the dbt project on mul - [String functions](#String-functions) - [charindex](#charindex-source) - [concat](#concat-source) + - [json](#json-source) - [Aggregate functions](#Aggregate-functions) - [stddev](#stddev-source) - [string_agg](#string_agg-source) @@ -275,6 +276,12 @@ Usage: To pass a string as argument, make sure to use double quotes: `{{ pm_utils.concat('"Field_A"', "' - '", '"Field_B"') }}` +#### json ([source](macros/string_functions/json.sql)) +This macro returns the value defined in the path of a JSON string. The first argument indicates the field that stores the JSON string and the second argument is the path for which the value should be returned. + +Usage: +`{{ pm_utils.json('[field]', '[path]') }}` + ### Aggregate functions #### stddev ([source](macros/aggregate_functions/stddev.sql)) diff --git a/dbt_project.yml b/dbt_project.yml index cbd925a..1f4f14d 100644 --- a/dbt_project.yml +++ b/dbt_project.yml @@ -1,5 +1,5 @@ name: 'pm_utils' -version: '2.0.0' +version: '2.1.0' config-version: 2 require-dbt-version: [">=1.0.0", "<2.0.0"] diff --git a/integration_tests/models/schema.yml b/integration_tests/models/schema.yml index f752e58..42bbe6c 100644 --- a/integration_tests/models/schema.yml +++ b/integration_tests/models/schema.yml @@ -171,3 +171,12 @@ models: - equal_value: actual: '"Only_weekend"' expected: '"Only_weekend_expected"' + + - name: test_json + tests: + - equal_value: + actual: '"One_level_field"' + expected: '"One_level_field_expected"' + - equal_value: + actual: '"Two_level_field"' + expected: '"Two_level_field_expected"' diff --git a/integration_tests/models/test_json.sql b/integration_tests/models/test_json.sql new file mode 100644 index 0000000..905ce4d --- /dev/null +++ b/integration_tests/models/test_json.sql @@ -0,0 +1,16 @@ +with Input_data as ( + select + '{"Field_A":"ABC"}' as "Column_A", + '{"Field_A": {"Field_B": "DEF"}}' as "Column_B", + null as "Column_C" +) + +select + {# Get value from a one level path. #} + {{ pm_utils.json('"Column_A"', 'Field_A') }} as "One_level_field", + 'ABC' as "One_level_field_expected", + + {# Get value from a two level path. #} + {{ pm_utils.json('"Column_B"', 'Field_A.Field_B') }} as "Two_level_field", + 'DEF' as "Two_level_field_expected" +from Input_data diff --git a/macros/string_functions/json.sql b/macros/string_functions/json.sql new file mode 100644 index 0000000..1e068ef --- /dev/null +++ b/macros/string_functions/json.sql @@ -0,0 +1,9 @@ +{% macro json(field, path) %} + +{% if target.type == 'snowflake' %} + JSON_EXTRACT_PATH_TEXT({{ field }}, '{{ path }}') +{% elif target.type == 'sqlserver' %} + json_value({{ field }}, '$.{{ path }}') +{% endif %} + +{% endmacro %}