diff --git a/README.md b/README.md index d227677..be06bdd 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,7 @@ To run the tests: - [expect_table_column_count_to_be_between](#expect_table_column_count_to_be_between) - [expect_table_column_count_to_equal_other_table](#expect_table_column_count_to_equal_other_table) - [expect_table_column_count_to_equal](#expect_table_column_count_to_equal) +- [expect_table_columns_to_not_contain_set](#expect_table_columns_to_not_contain_set) - [expect_table_columns_to_contain_set](#expect_table_columns_to_contain_set) - [expect_table_columns_to_match_ordered_list](#expect_table_columns_to_match_ordered_list) - [expect_table_columns_to_match_set](#expect_table_columns_to_match_set) @@ -225,6 +226,20 @@ models: # or seeds: compare_model: ref("other_model") ``` +### [expect_table_columns_to_not_contain_set](macros/schema_tests/table_shape/expect_table_columns_to_not_contain_set.sql) + +Expect the columns in a model not to contain a given list. + +*Applies to:* Model, Seed, Source + +```yaml +models: # or seeds: + - name: my_model + tests: + - dbt_expectations.expect_table_columns_to_not_contain_set: + column_list: ["col_a", "col_b"] + transform: uppper # (Optional) +``` ### [expect_table_columns_to_contain_set](macros/schema_tests/table_shape/expect_table_columns_to_contain_set.sql) Expect the columns in a model to contain a given list. diff --git a/integration_tests/models/schema_tests/schema.yml b/integration_tests/models/schema_tests/schema.yml index 8a1d6bb..125302f 100644 --- a/integration_tests/models/schema_tests/schema.yml +++ b/integration_tests/models/schema_tests/schema.yml @@ -166,6 +166,8 @@ models: column_list: ["idx", "date_col", "col_numeric_a", "col_numeric_b", "col_string_a", "col_string_b", "col_null"] - dbt_expectations.expect_table_column_count_to_equal_other_table: compare_model: ref("data_test") + - dbt_expectations.expect_table_columns_to_not_contain_set: + column_list: ["col_numeric_c", "col_string_d"] - dbt_expectations.expression_is_true: expression: (col_numeric_a + col_numeric_b = 1) - dbt_expectations.equal_expression: diff --git a/macros/schema_tests/table_shape/expect_table_columns_to_not_contain_set.sql b/macros/schema_tests/table_shape/expect_table_columns_to_not_contain_set.sql new file mode 100644 index 0000000..a6f3bea --- /dev/null +++ b/macros/schema_tests/table_shape/expect_table_columns_to_not_contain_set.sql @@ -0,0 +1,28 @@ +{%- test expect_table_columns_to_not_contain_set(model, column_list, transform="upper") -%} +{%- if execute -%} + {%- set column_list = column_list | map(transform) | list -%} + {%- set relation_column_names = dbt_expectations._get_column_list(model, transform) -%} + {%- set matching_columns = dbt_expectations._list_intersect(column_list, relation_column_names) -%} + with relation_columns as ( + + {% for col_name in relation_column_names %} + select cast('{{ col_name }}' as {{ dbt_utils.type_string() }}) as relation_column + {% if not loop.last %}union all{% endif %} + {% endfor %} + ), + input_columns as ( + + {% for col_name in column_list %} + select cast('{{ col_name }}' as {{ dbt_utils.type_string() }}) as input_column + {% if not loop.last %}union all{% endif %} + {% endfor %} + ) + -- catch any column in input list that is in the list of table columns + select * + from + input_columns i + inner join + relation_columns r on r.relation_column = i.input_column + +{%- endif -%} +{%- endtest -%}