From ff9a0f1b5d55d54f85e990ee673cdc09be9bea2c Mon Sep 17 00:00:00 2001 From: Joost Boonzajer Flaes Date: Wed, 25 Mar 2026 19:34:39 +0200 Subject: [PATCH 1/3] feat: add _with_context variants for generic tests Adds six new elementary generic tests that extend common dbt/dbt_utils/dbt_expectations tests with a `context_columns` parameter, allowing users to specify which additional columns are returned alongside failing rows. If `context_columns` is omitted, all columns are returned. New tests: - elementary.not_null_with_context - elementary.accepted_range_with_context - elementary.expect_column_values_to_not_be_null_with_context - elementary.expect_column_values_to_be_unique_with_context - elementary.expect_column_values_to_match_regex_with_context - elementary.relationships_with_context Co-Authored-By: Claude Sonnet 4.6 --- .../test_accepted_range_with_context.sql | 29 ++++++++++++++++++ ...olumn_values_to_be_unique_with_context.sql | 30 +++++++++++++++++++ ...umn_values_to_match_regex_with_context.sql | 26 ++++++++++++++++ ...umn_values_to_not_be_null_with_context.sql | 25 ++++++++++++++++ .../edr/tests/test_not_null_with_context.sql | 24 +++++++++++++++ .../tests/test_relationships_with_context.sql | 25 ++++++++++++++++ macros/utils/common_test_configs.sql | 30 +++++++++++++++++++ 7 files changed, 189 insertions(+) create mode 100644 macros/edr/tests/test_accepted_range_with_context.sql create mode 100644 macros/edr/tests/test_expect_column_values_to_be_unique_with_context.sql create mode 100644 macros/edr/tests/test_expect_column_values_to_match_regex_with_context.sql create mode 100644 macros/edr/tests/test_expect_column_values_to_not_be_null_with_context.sql create mode 100644 macros/edr/tests/test_not_null_with_context.sql create mode 100644 macros/edr/tests/test_relationships_with_context.sql diff --git a/macros/edr/tests/test_accepted_range_with_context.sql b/macros/edr/tests/test_accepted_range_with_context.sql new file mode 100644 index 000000000..85608912c --- /dev/null +++ b/macros/edr/tests/test_accepted_range_with_context.sql @@ -0,0 +1,29 @@ +{% test accepted_range_with_context(model, column_name, min_value=none, max_value=none, inclusive=true, context_columns=none) %} + {%- if context_columns is not none and context_columns is iterable and context_columns is not string %} + {%- set existing_column_names = adapter.get_columns_in_relation(model) | map(attribute='name') | map('lower') | list %} + {%- set select_cols = [column_name] %} + {%- for col in context_columns %} + {%- if col | lower == column_name | lower %} + {# already included, skip #} + {%- elif col | lower not in existing_column_names %} + {%- do log("WARNING [accepted_range_with_context]: column '" ~ col ~ "' does not exist in model '" ~ model.name ~ "' and will be skipped.", info=true) %} + {%- else %} + {%- do select_cols.append(col) %} + {%- endif %} + {%- endfor %} + {%- set select_clause = select_cols | join(', ') %} + {%- else %} + {%- set select_clause = '*' %} + {%- endif %} + + select {{ select_clause }} + from {{ model }} + where + 1 = 2 + {%- if min_value is not none %} + or not {{ column_name }} >{{- "=" if inclusive }} {{ min_value }} + {%- endif %} + {%- if max_value is not none %} + or not {{ column_name }} <{{- "=" if inclusive }} {{ max_value }} + {%- endif %} +{% endtest %} diff --git a/macros/edr/tests/test_expect_column_values_to_be_unique_with_context.sql b/macros/edr/tests/test_expect_column_values_to_be_unique_with_context.sql new file mode 100644 index 000000000..952454490 --- /dev/null +++ b/macros/edr/tests/test_expect_column_values_to_be_unique_with_context.sql @@ -0,0 +1,30 @@ +{% test expect_column_values_to_be_unique_with_context(model, column_name, row_condition=none, context_columns=none) %} + {%- if context_columns is not none and context_columns is iterable and context_columns is not string %} + {%- set existing_column_names = adapter.get_columns_in_relation(model) | map(attribute='name') | map('lower') | list %} + {%- set select_cols = [column_name] %} + {%- for col in context_columns %} + {%- if col | lower == column_name | lower %} + {# already included, skip #} + {%- elif col | lower not in existing_column_names %} + {%- do log("WARNING [expect_column_values_to_be_unique_with_context]: column '" ~ col ~ "' does not exist in model '" ~ model.name ~ "' and will be skipped.", info=true) %} + {%- else %} + {%- do select_cols.append(col) %} + {%- endif %} + {%- endfor %} + {%- set select_clause = select_cols | join(', ') %} + {%- else %} + {%- set select_clause = '*' %} + {%- endif %} + + select {{ select_clause }} + from ( + select + *, + count(*) over (partition by {{ column_name }}) as n_records + from {{ model }} + {%- if row_condition %} + where {{ row_condition }} + {%- endif %} + ) validation + where n_records > 1 +{% endtest %} diff --git a/macros/edr/tests/test_expect_column_values_to_match_regex_with_context.sql b/macros/edr/tests/test_expect_column_values_to_match_regex_with_context.sql new file mode 100644 index 000000000..82e096f95 --- /dev/null +++ b/macros/edr/tests/test_expect_column_values_to_match_regex_with_context.sql @@ -0,0 +1,26 @@ +{% test expect_column_values_to_match_regex_with_context(model, column_name, regex, row_condition=none, is_raw=false, flags="", context_columns=none) %} + {%- if context_columns is not none and context_columns is iterable and context_columns is not string %} + {%- set existing_column_names = adapter.get_columns_in_relation(model) | map(attribute='name') | map('lower') | list %} + {%- set select_cols = [column_name] %} + {%- for col in context_columns %} + {%- if col | lower == column_name | lower %} + {# already included, skip #} + {%- elif col | lower not in existing_column_names %} + {%- do log("WARNING [expect_column_values_to_match_regex_with_context]: column '" ~ col ~ "' does not exist in model '" ~ model.name ~ "' and will be skipped.", info=true) %} + {%- else %} + {%- do select_cols.append(col) %} + {%- endif %} + {%- endfor %} + {%- set select_clause = select_cols | join(', ') %} + {%- else %} + {%- set select_clause = '*' %} + {%- endif %} + + select {{ select_clause }} + from {{ model }} + where + {{ dbt_expectations.regexp_instr(column_name, regex, is_raw=is_raw, flags=flags) }} = 0 + {%- if row_condition %} + and {{ row_condition }} + {%- endif %} +{% endtest %} diff --git a/macros/edr/tests/test_expect_column_values_to_not_be_null_with_context.sql b/macros/edr/tests/test_expect_column_values_to_not_be_null_with_context.sql new file mode 100644 index 000000000..fb3c29558 --- /dev/null +++ b/macros/edr/tests/test_expect_column_values_to_not_be_null_with_context.sql @@ -0,0 +1,25 @@ +{% test expect_column_values_to_not_be_null_with_context(model, column_name, row_condition=none, context_columns=none) %} + {%- if context_columns is not none and context_columns is iterable and context_columns is not string %} + {%- set existing_column_names = adapter.get_columns_in_relation(model) | map(attribute='name') | map('lower') | list %} + {%- set select_cols = [column_name] %} + {%- for col in context_columns %} + {%- if col | lower == column_name | lower %} + {# already included, skip #} + {%- elif col | lower not in existing_column_names %} + {%- do log("WARNING [expect_column_values_to_not_be_null_with_context]: column '" ~ col ~ "' does not exist in model '" ~ model.name ~ "' and will be skipped.", info=true) %} + {%- else %} + {%- do select_cols.append(col) %} + {%- endif %} + {%- endfor %} + {%- set select_clause = select_cols | join(', ') %} + {%- else %} + {%- set select_clause = '*' %} + {%- endif %} + + select {{ select_clause }} + from {{ model }} + where {{ column_name }} is null + {%- if row_condition %} + and {{ row_condition }} + {%- endif %} +{% endtest %} diff --git a/macros/edr/tests/test_not_null_with_context.sql b/macros/edr/tests/test_not_null_with_context.sql new file mode 100644 index 000000000..f324657f3 --- /dev/null +++ b/macros/edr/tests/test_not_null_with_context.sql @@ -0,0 +1,24 @@ +{% test not_null_with_context(model, column_name, context_columns=none) %} + {%- if context_columns is not none and context_columns is iterable and context_columns is not string %} + {%- set existing_column_names = adapter.get_columns_in_relation(model) | map(attribute='name') | map('lower') | list %} + + {%- set select_cols = [column_name] %} + {%- for col in context_columns %} + {%- if col | lower == column_name | lower %} + {# already included, skip #} + {%- elif col | lower not in existing_column_names %} + {%- do log("WARNING [not_null_with_context]: column '" ~ col ~ "' does not exist in model '" ~ model.name ~ "' and will be skipped.", info=true) %} + {%- else %} + {%- do select_cols.append(col) %} + {%- endif %} + {%- endfor %} + select + {{ select_cols | join(', ') }} + from {{ model }} + where {{ column_name }} is null + {%- else %} + select * + from {{ model }} + where {{ column_name }} is null + {%- endif %} +{% endtest %} diff --git a/macros/edr/tests/test_relationships_with_context.sql b/macros/edr/tests/test_relationships_with_context.sql new file mode 100644 index 000000000..f11705664 --- /dev/null +++ b/macros/edr/tests/test_relationships_with_context.sql @@ -0,0 +1,25 @@ +{% test relationships_with_context(model, column_name, to, field, context_columns=none) %} + {%- if context_columns is not none and context_columns is iterable and context_columns is not string %} + {%- set existing_column_names = adapter.get_columns_in_relation(model) | map(attribute='name') | map('lower') | list %} + {%- set select_cols = ['child.' ~ column_name] %} + {%- for col in context_columns %} + {%- if col | lower == column_name | lower %} + {# already included, skip #} + {%- elif col | lower not in existing_column_names %} + {%- do log("WARNING [relationships_with_context]: column '" ~ col ~ "' does not exist in model '" ~ model.name ~ "' and will be skipped.", info=true) %} + {%- else %} + {%- do select_cols.append('child.' ~ col) %} + {%- endif %} + {%- endfor %} + {%- set select_clause = select_cols | join(', ') %} + {%- else %} + {%- set select_clause = 'child.*' %} + {%- endif %} + + select {{ select_clause }} + from {{ model }} as child + left join {{ to }} as parent + on child.{{ column_name }} = parent.{{ field }} + where child.{{ column_name }} is not null + and parent.{{ field }} is null +{% endtest %} diff --git a/macros/utils/common_test_configs.sql b/macros/utils/common_test_configs.sql index 039aceaac..26edd2e15 100644 --- a/macros/utils/common_test_configs.sql +++ b/macros/utils/common_test_configs.sql @@ -450,6 +450,36 @@ "collect_metrics": { "description": "Collects metrics for the specified column or table. The test will always pass." }, + "not_null_with_context": { + "quality_dimension": "completeness", + "failed_row_count_calc": "count(*)", + "description": "Validates that there are no null values in a column, returning additional context columns alongside failing rows. If no context_columns are specified, all columns are returned.", + }, + "accepted_range_with_context": { + "quality_dimension": "validity", + "failed_row_count_calc": "count(*)", + "description": "Validates that column values fall within an accepted range, returning additional context columns alongside failing rows. If no context_columns are specified, all columns are returned.", + }, + "expect_column_values_to_not_be_null_with_context": { + "quality_dimension": "completeness", + "failed_row_count_calc": "count(*)", + "description": "Expects column values to not be null, returning additional context columns alongside failing rows. If no context_columns are specified, all columns are returned.", + }, + "expect_column_values_to_be_unique_with_context": { + "quality_dimension": "uniqueness", + "failed_row_count_calc": "count(*)", + "description": "Expects column values to be unique, returning all duplicate rows with additional context columns. If no context_columns are specified, all columns are returned.", + }, + "expect_column_values_to_match_regex_with_context": { + "quality_dimension": "validity", + "failed_row_count_calc": "count(*)", + "description": "Expects column values to match a given regular expression, returning additional context columns alongside failing rows. If no context_columns are specified, all columns are returned.", + }, + "relationships_with_context": { + "quality_dimension": "consistency", + "failed_row_count_calc": "count(*)", + "description": "Validates referential integrity between a child and parent table, returning additional context columns alongside failing rows. If no context_columns are specified, all columns are returned.", + }, }, } %} {% do return(common_tests_configs_mapping) %} From d165a3b966dea378b2d4c0cace08934f346fa2c2 Mon Sep 17 00:00:00 2001 From: Joost Boonzajer Flaes Date: Wed, 25 Mar 2026 23:15:56 +0200 Subject: [PATCH 2/3] fix: address CodeRabbit review comments on _with_context tests - accepted_range_with_context: raise compiler error when both min_value and max_value are omitted, preventing a silent always-pass condition - expect_column_values_to_be_unique_with_context: use explicit column list from adapter.get_columns_in_relation instead of SELECT * to prevent the computed n_records window column from leaking into the output Co-Authored-By: Claude Sonnet 4.6 --- macros/edr/tests/test_accepted_range_with_context.sql | 4 ++++ ...est_expect_column_values_to_be_unique_with_context.sql | 8 +++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/macros/edr/tests/test_accepted_range_with_context.sql b/macros/edr/tests/test_accepted_range_with_context.sql index 85608912c..76cf7e589 100644 --- a/macros/edr/tests/test_accepted_range_with_context.sql +++ b/macros/edr/tests/test_accepted_range_with_context.sql @@ -1,4 +1,8 @@ {% test accepted_range_with_context(model, column_name, min_value=none, max_value=none, inclusive=true, context_columns=none) %} + {%- if min_value is none and max_value is none %} + {{ exceptions.raise_compiler_error("accepted_range_with_context: at least one of min_value or max_value must be provided.") }} + {%- endif %} + {%- if context_columns is not none and context_columns is iterable and context_columns is not string %} {%- set existing_column_names = adapter.get_columns_in_relation(model) | map(attribute='name') | map('lower') | list %} {%- set select_cols = [column_name] %} diff --git a/macros/edr/tests/test_expect_column_values_to_be_unique_with_context.sql b/macros/edr/tests/test_expect_column_values_to_be_unique_with_context.sql index 952454490..421f8baa2 100644 --- a/macros/edr/tests/test_expect_column_values_to_be_unique_with_context.sql +++ b/macros/edr/tests/test_expect_column_values_to_be_unique_with_context.sql @@ -1,11 +1,13 @@ {% test expect_column_values_to_be_unique_with_context(model, column_name, row_condition=none, context_columns=none) %} + {%- set all_columns = adapter.get_columns_in_relation(model) | map(attribute='name') | list %} + {%- set all_columns_lower = all_columns | map('lower') | list %} + {%- if context_columns is not none and context_columns is iterable and context_columns is not string %} - {%- set existing_column_names = adapter.get_columns_in_relation(model) | map(attribute='name') | map('lower') | list %} {%- set select_cols = [column_name] %} {%- for col in context_columns %} {%- if col | lower == column_name | lower %} {# already included, skip #} - {%- elif col | lower not in existing_column_names %} + {%- elif col | lower not in all_columns_lower %} {%- do log("WARNING [expect_column_values_to_be_unique_with_context]: column '" ~ col ~ "' does not exist in model '" ~ model.name ~ "' and will be skipped.", info=true) %} {%- else %} {%- do select_cols.append(col) %} @@ -13,7 +15,7 @@ {%- endfor %} {%- set select_clause = select_cols | join(', ') %} {%- else %} - {%- set select_clause = '*' %} + {%- set select_clause = all_columns | join(', ') %} {%- endif %} select {{ select_clause }} From 227528f068d01048902f79488d8aa6995e8fe300 Mon Sep 17 00:00:00 2001 From: Joost Boonzajer Flaes Date: Wed, 25 Mar 2026 23:18:39 +0200 Subject: [PATCH 3/3] style: apply sqlfmt formatting to _with_context tests Co-Authored-By: Claude Sonnet 4.6 --- .../test_accepted_range_with_context.sql | 45 ++++++++++++++----- ...olumn_values_to_be_unique_with_context.sql | 44 ++++++++++-------- ...umn_values_to_match_regex_with_context.sql | 45 +++++++++++++------ ...umn_values_to_not_be_null_with_context.sql | 37 +++++++++------ .../edr/tests/test_not_null_with_context.sql | 29 +++++++----- .../tests/test_relationships_with_context.sql | 38 ++++++++++------ 6 files changed, 156 insertions(+), 82 deletions(-) diff --git a/macros/edr/tests/test_accepted_range_with_context.sql b/macros/edr/tests/test_accepted_range_with_context.sql index 76cf7e589..1dafb0ce6 100644 --- a/macros/edr/tests/test_accepted_range_with_context.sql +++ b/macros/edr/tests/test_accepted_range_with_context.sql @@ -1,23 +1,44 @@ -{% test accepted_range_with_context(model, column_name, min_value=none, max_value=none, inclusive=true, context_columns=none) %} +{% test accepted_range_with_context( + model, + column_name, + min_value=none, + max_value=none, + inclusive=true, + context_columns=none +) %} {%- if min_value is none and max_value is none %} - {{ exceptions.raise_compiler_error("accepted_range_with_context: at least one of min_value or max_value must be provided.") }} + {{ + exceptions.raise_compiler_error( + "accepted_range_with_context: at least one of min_value or max_value must be provided." + ) + }} {%- endif %} {%- if context_columns is not none and context_columns is iterable and context_columns is not string %} - {%- set existing_column_names = adapter.get_columns_in_relation(model) | map(attribute='name') | map('lower') | list %} + {%- set existing_column_names = ( + adapter.get_columns_in_relation(model) + | map(attribute="name") + | map("lower") + | list + ) %} {%- set select_cols = [column_name] %} {%- for col in context_columns %} {%- if col | lower == column_name | lower %} - {# already included, skip #} + {# already included, skip #} {%- elif col | lower not in existing_column_names %} - {%- do log("WARNING [accepted_range_with_context]: column '" ~ col ~ "' does not exist in model '" ~ model.name ~ "' and will be skipped.", info=true) %} - {%- else %} - {%- do select_cols.append(col) %} + {%- do log( + "WARNING [accepted_range_with_context]: column '" + ~ col + ~ "' does not exist in model '" + ~ model.name + ~ "' and will be skipped.", + info=true, + ) %} + {%- else %} {%- do select_cols.append(col) %} {%- endif %} {%- endfor %} - {%- set select_clause = select_cols | join(', ') %} - {%- else %} - {%- set select_clause = '*' %} + {%- set select_clause = select_cols | join(", ") %} + {%- else %} {%- set select_clause = "*" %} {%- endif %} select {{ select_clause }} @@ -25,9 +46,9 @@ where 1 = 2 {%- if min_value is not none %} - or not {{ column_name }} >{{- "=" if inclusive }} {{ min_value }} + or not {{ column_name }} >{{- "=" if inclusive }} {{ min_value }} {%- endif %} {%- if max_value is not none %} - or not {{ column_name }} <{{- "=" if inclusive }} {{ max_value }} + or not {{ column_name }} <{{- "=" if inclusive }} {{ max_value }} {%- endif %} {% endtest %} diff --git a/macros/edr/tests/test_expect_column_values_to_be_unique_with_context.sql b/macros/edr/tests/test_expect_column_values_to_be_unique_with_context.sql index 421f8baa2..a6fdfd01d 100644 --- a/macros/edr/tests/test_expect_column_values_to_be_unique_with_context.sql +++ b/macros/edr/tests/test_expect_column_values_to_be_unique_with_context.sql @@ -1,32 +1,38 @@ -{% test expect_column_values_to_be_unique_with_context(model, column_name, row_condition=none, context_columns=none) %} - {%- set all_columns = adapter.get_columns_in_relation(model) | map(attribute='name') | list %} - {%- set all_columns_lower = all_columns | map('lower') | list %} +{% test expect_column_values_to_be_unique_with_context( + model, column_name, row_condition=none, context_columns=none +) %} + {%- set all_columns = ( + adapter.get_columns_in_relation(model) | map(attribute="name") | list + ) %} + {%- set all_columns_lower = all_columns | map("lower") | list %} {%- if context_columns is not none and context_columns is iterable and context_columns is not string %} {%- set select_cols = [column_name] %} {%- for col in context_columns %} {%- if col | lower == column_name | lower %} - {# already included, skip #} + {# already included, skip #} {%- elif col | lower not in all_columns_lower %} - {%- do log("WARNING [expect_column_values_to_be_unique_with_context]: column '" ~ col ~ "' does not exist in model '" ~ model.name ~ "' and will be skipped.", info=true) %} - {%- else %} - {%- do select_cols.append(col) %} + {%- do log( + "WARNING [expect_column_values_to_be_unique_with_context]: column '" + ~ col + ~ "' does not exist in model '" + ~ model.name + ~ "' and will be skipped.", + info=true, + ) %} + {%- else %} {%- do select_cols.append(col) %} {%- endif %} {%- endfor %} - {%- set select_clause = select_cols | join(', ') %} - {%- else %} - {%- set select_clause = all_columns | join(', ') %} + {%- set select_clause = select_cols | join(", ") %} + {%- else %} {%- set select_clause = all_columns | join(", ") %} {%- endif %} select {{ select_clause }} - from ( - select - *, - count(*) over (partition by {{ column_name }}) as n_records - from {{ model }} - {%- if row_condition %} - where {{ row_condition }} - {%- endif %} - ) validation + from + ( + select *, count(*) over (partition by {{ column_name }}) as n_records + from {{ model }} + {%- if row_condition %} where {{ row_condition }} {%- endif %} + ) validation where n_records > 1 {% endtest %} diff --git a/macros/edr/tests/test_expect_column_values_to_match_regex_with_context.sql b/macros/edr/tests/test_expect_column_values_to_match_regex_with_context.sql index 82e096f95..61b8a9fac 100644 --- a/macros/edr/tests/test_expect_column_values_to_match_regex_with_context.sql +++ b/macros/edr/tests/test_expect_column_values_to_match_regex_with_context.sql @@ -1,26 +1,45 @@ -{% test expect_column_values_to_match_regex_with_context(model, column_name, regex, row_condition=none, is_raw=false, flags="", context_columns=none) %} +{% test expect_column_values_to_match_regex_with_context( + model, + column_name, + regex, + row_condition=none, + is_raw=false, + flags="", + context_columns=none +) %} {%- if context_columns is not none and context_columns is iterable and context_columns is not string %} - {%- set existing_column_names = adapter.get_columns_in_relation(model) | map(attribute='name') | map('lower') | list %} + {%- set existing_column_names = ( + adapter.get_columns_in_relation(model) + | map(attribute="name") + | map("lower") + | list + ) %} {%- set select_cols = [column_name] %} {%- for col in context_columns %} {%- if col | lower == column_name | lower %} - {# already included, skip #} + {# already included, skip #} {%- elif col | lower not in existing_column_names %} - {%- do log("WARNING [expect_column_values_to_match_regex_with_context]: column '" ~ col ~ "' does not exist in model '" ~ model.name ~ "' and will be skipped.", info=true) %} - {%- else %} - {%- do select_cols.append(col) %} + {%- do log( + "WARNING [expect_column_values_to_match_regex_with_context]: column '" + ~ col + ~ "' does not exist in model '" + ~ model.name + ~ "' and will be skipped.", + info=true, + ) %} + {%- else %} {%- do select_cols.append(col) %} {%- endif %} {%- endfor %} - {%- set select_clause = select_cols | join(', ') %} - {%- else %} - {%- set select_clause = '*' %} + {%- set select_clause = select_cols | join(", ") %} + {%- else %} {%- set select_clause = "*" %} {%- endif %} select {{ select_clause }} from {{ model }} where - {{ dbt_expectations.regexp_instr(column_name, regex, is_raw=is_raw, flags=flags) }} = 0 - {%- if row_condition %} - and {{ row_condition }} - {%- endif %} + {{ + dbt_expectations.regexp_instr( + column_name, regex, is_raw=is_raw, flags=flags + ) + }} = 0 {%- if row_condition %} and {{ row_condition }} {%- endif %} {% endtest %} diff --git a/macros/edr/tests/test_expect_column_values_to_not_be_null_with_context.sql b/macros/edr/tests/test_expect_column_values_to_not_be_null_with_context.sql index fb3c29558..df3fbac46 100644 --- a/macros/edr/tests/test_expect_column_values_to_not_be_null_with_context.sql +++ b/macros/edr/tests/test_expect_column_values_to_not_be_null_with_context.sql @@ -1,25 +1,36 @@ -{% test expect_column_values_to_not_be_null_with_context(model, column_name, row_condition=none, context_columns=none) %} +{% test expect_column_values_to_not_be_null_with_context( + model, column_name, row_condition=none, context_columns=none +) %} {%- if context_columns is not none and context_columns is iterable and context_columns is not string %} - {%- set existing_column_names = adapter.get_columns_in_relation(model) | map(attribute='name') | map('lower') | list %} + {%- set existing_column_names = ( + adapter.get_columns_in_relation(model) + | map(attribute="name") + | map("lower") + | list + ) %} {%- set select_cols = [column_name] %} {%- for col in context_columns %} {%- if col | lower == column_name | lower %} - {# already included, skip #} + {# already included, skip #} {%- elif col | lower not in existing_column_names %} - {%- do log("WARNING [expect_column_values_to_not_be_null_with_context]: column '" ~ col ~ "' does not exist in model '" ~ model.name ~ "' and will be skipped.", info=true) %} - {%- else %} - {%- do select_cols.append(col) %} + {%- do log( + "WARNING [expect_column_values_to_not_be_null_with_context]: column '" + ~ col + ~ "' does not exist in model '" + ~ model.name + ~ "' and will be skipped.", + info=true, + ) %} + {%- else %} {%- do select_cols.append(col) %} {%- endif %} {%- endfor %} - {%- set select_clause = select_cols | join(', ') %} - {%- else %} - {%- set select_clause = '*' %} + {%- set select_clause = select_cols | join(", ") %} + {%- else %} {%- set select_clause = "*" %} {%- endif %} select {{ select_clause }} from {{ model }} - where {{ column_name }} is null - {%- if row_condition %} - and {{ row_condition }} - {%- endif %} + where + {{ column_name }} is null + {%- if row_condition %} and {{ row_condition }} {%- endif %} {% endtest %} diff --git a/macros/edr/tests/test_not_null_with_context.sql b/macros/edr/tests/test_not_null_with_context.sql index f324657f3..0073ea35b 100644 --- a/macros/edr/tests/test_not_null_with_context.sql +++ b/macros/edr/tests/test_not_null_with_context.sql @@ -1,24 +1,31 @@ {% test not_null_with_context(model, column_name, context_columns=none) %} {%- if context_columns is not none and context_columns is iterable and context_columns is not string %} - {%- set existing_column_names = adapter.get_columns_in_relation(model) | map(attribute='name') | map('lower') | list %} + {%- set existing_column_names = ( + adapter.get_columns_in_relation(model) + | map(attribute="name") + | map("lower") + | list + ) %} {%- set select_cols = [column_name] %} {%- for col in context_columns %} {%- if col | lower == column_name | lower %} - {# already included, skip #} + {# already included, skip #} {%- elif col | lower not in existing_column_names %} - {%- do log("WARNING [not_null_with_context]: column '" ~ col ~ "' does not exist in model '" ~ model.name ~ "' and will be skipped.", info=true) %} - {%- else %} - {%- do select_cols.append(col) %} + {%- do log( + "WARNING [not_null_with_context]: column '" + ~ col + ~ "' does not exist in model '" + ~ model.name + ~ "' and will be skipped.", + info=true, + ) %} + {%- else %} {%- do select_cols.append(col) %} {%- endif %} {%- endfor %} - select - {{ select_cols | join(', ') }} - from {{ model }} - where {{ column_name }} is null - {%- else %} - select * + select {{ select_cols | join(", ") }} from {{ model }} where {{ column_name }} is null + {%- else %} select * from {{ model }} where {{ column_name }} is null {%- endif %} {% endtest %} diff --git a/macros/edr/tests/test_relationships_with_context.sql b/macros/edr/tests/test_relationships_with_context.sql index f11705664..3a4fe37e5 100644 --- a/macros/edr/tests/test_relationships_with_context.sql +++ b/macros/edr/tests/test_relationships_with_context.sql @@ -1,25 +1,35 @@ -{% test relationships_with_context(model, column_name, to, field, context_columns=none) %} +{% test relationships_with_context( + model, column_name, to, field, context_columns=none +) %} {%- if context_columns is not none and context_columns is iterable and context_columns is not string %} - {%- set existing_column_names = adapter.get_columns_in_relation(model) | map(attribute='name') | map('lower') | list %} - {%- set select_cols = ['child.' ~ column_name] %} + {%- set existing_column_names = ( + adapter.get_columns_in_relation(model) + | map(attribute="name") + | map("lower") + | list + ) %} + {%- set select_cols = ["child." ~ column_name] %} {%- for col in context_columns %} {%- if col | lower == column_name | lower %} - {# already included, skip #} + {# already included, skip #} {%- elif col | lower not in existing_column_names %} - {%- do log("WARNING [relationships_with_context]: column '" ~ col ~ "' does not exist in model '" ~ model.name ~ "' and will be skipped.", info=true) %} - {%- else %} - {%- do select_cols.append('child.' ~ col) %} + {%- do log( + "WARNING [relationships_with_context]: column '" + ~ col + ~ "' does not exist in model '" + ~ model.name + ~ "' and will be skipped.", + info=true, + ) %} + {%- else %} {%- do select_cols.append("child." ~ col) %} {%- endif %} {%- endfor %} - {%- set select_clause = select_cols | join(', ') %} - {%- else %} - {%- set select_clause = 'child.*' %} + {%- set select_clause = select_cols | join(", ") %} + {%- else %} {%- set select_clause = "child.*" %} {%- endif %} select {{ select_clause }} from {{ model }} as child - left join {{ to }} as parent - on child.{{ column_name }} = parent.{{ field }} - where child.{{ column_name }} is not null - and parent.{{ field }} is null + left join {{ to }} as parent on child.{{ column_name }} = parent.{{ field }} + where child.{{ column_name }} is not null and parent.{{ field }} is null {% endtest %}