Перейти к основному содержимому

where

Определение

Фильтрует ресурс, который тестируется (модель, источник, сид или снимок).

Условие where вставляется в тестовый запрос, заменяя ссылку на ресурс на subquery. Например, тест not_null может выглядеть так:

select *
from my_model
where my_column is null

Если конфигурация where установлена на where date_column = current_date, то тестовый запрос будет обновлен до:

select *
from (select * from my_model where date_column = current_date) dbt_subquery
where my_column is null

Примеры

Настройте конкретный экземпляр общего (схемного) теста:

models/<filename>.yml

models:
- name: large_table
columns:
- name: my_column
data_tests:
- accepted_values:
arguments: # available in v1.10.5 and higher. Older versions can set the <argument_name> as the top-level property.
values: ["a", "b", "c"]
config:
where: "date_column = current_date"
- name: other_column
data_tests:
- not_null:
config:
where: "date_column < current_date"

Пользовательская логика

Контекст рендеринга для конфигурации where такой же, как и для всех конфигураций, определенных в файлах .yml. У вас есть доступ к {{ var() }} и {{ env_var() }}, но у вас нет доступа к пользовательским макросам для установки этой конфигурации. Если вы хотите использовать пользовательские макросы для шаблонизации фильтра where для определенных тестов, существует обходной путь.

dbt определяет макрос get_where_subquery.

dbt заменяет {{ model }} в определениях общих тестов на {{ get_where_subquery(relation) }}, где relation — это ref() или source() для тестируемого ресурса. Стандартная реализация этого макроса возвращает:

  • {{ relation }}, когда конфигурация where не определена (ref() или source())
  • (select * from {{ relation }} where {{ where }}) dbt_subquery, когда конфигурация where определена

Вы можете переопределить это поведение, выполнив следующие действия:

  • Определив пользовательский get_where_subquery в вашем корневом проекте
  • Определив пользовательский <adapter>__get_where_subquery кандидат на диспетчеризацию в вашем пакете или адаптере

Внутри определения этого макроса вы можете ссылаться на любые пользовательские макросы, которые вам нужны, опираясь на статические входные данные из конфигурации. В самом простом случае это позволяет вам соблюдать принцип DRY и не дублировать код, который иначе пришлось бы повторять во множестве разных .yml‑файлов. Поскольку макрос get_where_subquery вычисляется во время выполнения, ваши пользовательские макросы также могут включать получение результатов интроспективных запросов к базе данных.

Пример

Отфильтруйте тест так, чтобы он учитывал только данные за последние N дней, используя кросс‑платформенный макрос dbt dateadd(). Количество дней можно задать в строке‑шаблоне.

models/config.yml
models:
- name: my_model
columns:
- name: id
data_tests:
- unique:
config:
where: "date_column > __3_days_ago__" # строка-заглушка для статической конфигурации
macros/custom_get_where_subquery.sql
{% macro get_where_subquery(relation) -%}
{% set where = config.get('where') %}
{% if where %}
{% if "_days_ago__" in where %}
{# заменить строку-заглушку результатом пользовательского макроса #}
{% set where = replace_days_ago(where) %}
{% endif %}
{%- set filtered -%}
(select * from {{ relation }} where {{ where }}) dbt_subquery
{%- endset -%}
{% do return(filtered) %}
{%- else -%}
{% do return(relation) %}
{%- endif -%}
{%- endmacro %}

{% macro replace_days_ago(where_string) %}
{# Use regex to search the pattern for the number days #}
{# Default to 3 days when no number found #}
{% set re = modules.re %}
{% set days = 3 %}
{% set pattern = '__(\d+)_days_ago__' %}
{% set match = re.search(pattern, where_string) %}
{% if match %}
{% set days = match.group(1) | int %}
{% endif %}
{% set n_days_ago = dbt.dateadd('day', -days, current_timestamp()) %}
{% set result = re.sub(pattern, n_days_ago, where_string) %}
{{ return(result) }}
{% endmacro %}

Нашли ошибку?

0
Loading