использование макросов в dbt_project config-version:2

В нашем файле dbt_project.yml config-version: 1 есть две переменные в разных инкрементных моделях, для которых мы используем макрос с именем today()

vars:
  start_date: '{{ today(offset_days=-1) }}'
  end_date: '2999-12-31'

При тестировании перехода на dbt 0.17.2, config-version:2 мы столкнулись со следующей проблемой

Running with dbt=0.17.2
Encountered an error:
Compilation Error
  Could not render {{ today(offset_days=-1) }}: 'today' is undefined

Макрос, который мы построили в конце прошлого года. Я считаю, что dbt изменил способ ссылки на макропеременные, но не знаю, как с этим справиться.

-- returns current hour in YYYY-MM-DD-HH format,
-- optionally offset by N days (-N or +N) or M hours (-M or +M)
{%- macro current_hour(offset_days=0, offset_hours=0) -%}
  {%- set now = modules.datetime.datetime.now(modules.pytz.utc) -%}
  {%- set dt = now + modules.datetime.timedelta(days=offset_days, hours=offset_hours) -%}
  {{- dt.strftime("%Y-%m-%d-%H") -}}
{%- endmacro -%}

-- returns current day in YYYY-MM-DD format,
-- optionally offset by N days (-N or +N) or M hours (-M or +M)
{%- macro today(offset_days=0, offset_hours=0) -%}
  {{- current_hour(offset_days, offset_hours)[0:10] -}}
{%- endmacro -%}

-- accepts a timestamp string and returns a timestamo string
-- formatted like 'YYYY-MM-DD HH24:MI:SS.US', e.g. '2019-11-02 06:11:42.690000'
{%- macro dt_to_utc(ts_string) -%}
  TO_CHAR({{ ts_string }}::TIMESTAMPTZ, 'YYYY-MM-DD HH24:MI:SS.US')
{%- endmacro -%}

2 ответа

Решение

Я попробовал это на месте и заставил работать. Помимо того, что нужно проверить выше, переехали ли выvars быть на одном уровне с models в твоем dbt_project.ymlфайл (документы)?

models:
  ...

vars:
  start_date: '{{ today(offset_days=-1) }}'
  end_date: '2999-12-31'
  

Я действительно удивлен, что это работает! Переменные лучше всего подходят для жестко запрограммированных объектов, а не для динамических объектов.

Мне любопытно - почему бы просто не вызвать макрос напрямую, а не использовать переменную?

Ток:

where created_at >= {{ var('start_date') }}

Предложенный:

where created_at >= {{ today(offset_days=-1) }}

При этом мои паучьи чувства здесь немного покалывают - этот код делает ваш проект dbt неидемпотентным - если ваш производственный запуск dbt остановится на несколько дней подряд, этот фильтр приведет к отсутствию данных.

Обычно мы избегаем подобного паттерна. Вместо этого мы используем наши существующие версии моделей для построения любых сроков отсечения - вы можете увидеть больше примеров здесь.

Хм, просто некоторые основы, которые приходят на ум в первую очередь, потому что я не внес всех этих изменений, когда я перешел на 0.17.2, и у меня была аналогичная проблема:

  1. Вы указываете путь к макросу в dbt_project.yml?

    Ex. macro-paths: ["macros"]

  2. Я полагаю, вы добавили config-version: 2 на ваш dbt_project.yml?

  3. Двойные кавычки попробовать?"{{ today(offset_days=-1) }}"

Необязательно: вы создали макрос schema.yml

Другие вопросы по тегам