pre-hook & post-hook
- Models
- Seeds
- Snapshots
В этих примерах мы используем символ | для разделения двух различных вариантов форматирования SQL-запросов в pre-hooks и post-hooks. Первый вариант (без скобок) принимает один SQL-запрос в виде строки, в то время как второй (со скобками) принимает несколько SQL-запросов в виде массива строк. Замените SQL-STATEMENT на ваш SQL-запрос.
models:
<resource-path>:
+pre-hook: SQL-statement | [SQL-statement]
+post-hook: SQL-statement | [SQL-statement]
{{ config(
pre_hook="SQL-statement" | ["SQL-statement"],
post_hook="SQL-statement" | ["SQL-statement"],
) }}
select ...
В этих примерах мы используем символ | для разделения двух различных вариантов форматирования SQL-запросов в pre-hooks и post-hooks. Первый вариант (без скобок) принимает один SQL-запрос в виде строки, в то время как второй (со скобками) принимает несколько SQL-запросов в виде массива строк. Замените SQL-STATEMENT на ваш SQL-запрос.
seeds:
<resource-path>:
+pre-hook: SQL-statement | [SQL-statement]
+post-hook: SQL-statement | [SQL-statement]
В этих примерах мы используем символ | для разделения двух различных вариантов форматирования SQL-запросов в pre-hooks и post-hooks. Первый вариант (без скобок) принимает один SQL-запрос в виде строки, в то время как второй (со скобками) принимает несколько SQL-запросов в виде массива строк. Замените SQL-STATEMENT на ваш SQL-запрос.
snapshots:
<resource-path>:
+pre-hook: SQL-statement | [SQL-statement]
+post-hook: SQL-statement | [SQL-statement]
Определение
SQL-выражение (или список SQL-выражений), которое выполняется до или после построения модели, seed или snapshot.
Pre- и post-хуки также могут вызывать макросы, которые возвращают SQL-выражения. Если ваш макрос зависит от значений, доступных только во время выполнения, таких как использование конфигураций модели или вызовы ref() к другим ресурсам в качестве входных данных, вам нужно будет обернуть вызов макроса в дополнительный набор фигурных скобок.
Зачем использовать хуки?
dbt стремится предоставить весь необходимый шаблонный SQL (DDL, DML и DCL) через встроенные функции, которые можно быстро и лаконично настроить. В некоторых случаях может быть SQL, который вы хотите или должны выполнить, специфичный для функциональности вашей платформы данных, который dbt пока не предлагает как встроенную функцию. В таких случаях вы можете написать точный SQL, который вам нужен, используя контекст компиляции dbt, и передать его в pre- или post- хук для выполнения до или после вашей модели, seed или snapshot.
Метод render
Метод .render() обычно используется для разрешения или вычисления выражений Jinja (таких как {{ source(...) }}) во время выполнения.
При использовании флага --empty, dbt может пропустить обработку ref() или source() для оптимизации. Чтобы избежать ошибок компиляции и явно указать dbt обработать конкретное отношение (ref() или source()), используйте метод .render() в вашем файле модели. Например:
{{ config(
pre_hook = [
"alter external table {{ source('sys', 'customers').render() }} refresh"
]
) }}
select ...
Примеры
[Redshift] Выгрузка одной модели в S3
{{ config(
post_hook = "unload ('select from {{ this }}') to 's3:/bucket_name/{{ this }}"
) }}
select ...
См.: Документация Redshift по UNLOAD
[Apache Spark] Анализ таблиц после создания
models:
jaffle_shop: # это имя проекта
marts:
finance:
+post-hook:
# это может быть список
- "analyze table {{ this }} compute statistics for all columns"
# или вызов макроса
- "{{ analyze_table() }}"
Дополнительные примеры
Мы собрали более подробные примеры здесь.
Примечания по использованию
Хуки являются кумулятивными
Если вы определяете хуки как в вашем dbt_project.yml, так и в блоке config модели, оба набора хуков будут применены к вашей модели.
Порядок выполнения
Если определено несколько экземпляров любых хуков, dbt выполнит каждый хук в следующем порядке:
- Хуки из зависимых пакетов будут выполнены перед хуками в активном пакете.
- Хуки, определенные в самой модели, будут выполнены после хуков, определенных в
dbt_project.yml. - Хуки в данном контексте будут выполнены в порядке их определения.
Поведение транзакций
Если вы используете адаптер, который использует транзакции (например, Postgres или Redshift), стоит отметить, что по умолчанию хуки выполняются внутри той же транзакции, что и создаваемая модель.
Могут быть случаи, когда вам нужно выполнить эти хуки вне транзакции, например:
- Вы хотите выполнить
VACUUMвpost-hook, однако это не может быть выполнено в транзакции (Документация Redshift) - Вы хотите вставить запись в аудиторскую table в начале выполнения и не хотите, чтобы это выражение было отменено, если создание модели не удастся.
Чтобы достичь этого поведения, вы можете использовать один из следующих синтаксисов:
- Важное замечание: не используйте этот синтаксис, если вы используете базу данных, где dbt не поддерживает транзакции. Это включает базы данных, такие как Snowflake, BigQuery и Spark или Databricks.
- Используйте before_begin и after_commit
- Используйте словарь
- Используйте dbt_project.yml
Блок конфигурации: используйте вспомогательные макросы before_begin и after_commit
{{
config(
pre_hook=before_begin("SQL-statement"),
post_hook=after_commit("SQL-statement")
)
}}
select ...
Блок конфигурации: используйте словарь
{{
config(
pre_hook={
"sql": "SQL-statement",
"transaction": False
},
post_hook={
"sql": "SQL-statement",
"transaction": False
}
)
}}
select ...
dbt_project.yml: Используйте словарь
models:
+pre-hook:
sql: "SQL-statement"
transaction: false
+post-hook:
sql: "SQL-statement"
transaction: false