pre-hook & post-hook
- Models
- Seeds
- Snapshots
In these examples, we use the |
symbol to separate two different formatting options for SQL statements in pre-hooks and post-hooks. The first option (without brackets) accepts a single SQL statement as a string, while the second (with brackets) accepts multiple SQL statements as an array of strings. Replace SQL-STATEMENT
with your 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 ...
In these examples, we use the |
symbol to separate two different formatting options for SQL statements in pre-hooks and post-hooks. The first option (without brackets) accepts a single SQL statement as a string, while the second (with brackets) accepts multiple SQL statements as an array of strings. Replace SQL-STATEMENT
with your SQL.
seeds:
<resource-path>:
+pre-hook: SQL-statement | [SQL-statement]
+post-hook: SQL-statement | [SQL-statement]
In these examples, we use the |
symbol to separate two different formatting options for SQL statements in pre-hooks and post-hooks. The first option (without brackets) accepts a single SQL statement as a string, while the second (with brackets) accepts multiple SQL statements as an array of strings. Replace SQL-STATEMENT
with your SQL.
snapshots:
<resource-path>:
+pre-hook: SQL-statement | [SQL-statement]
+post-hook: SQL-statement | [SQL-statement]
Definition
A SQL statement (or list of SQL statements) to be run before or after a model, seed, or snapshot is built.
Pre- and post-hooks can also call macros that return SQL statements. If your macro depends on values available only at execution time, such as using model configurations or ref()
calls to other resources as inputs, you will need to wrap your macro call in an extra set of curly braces.
Why would I use hooks?
dbt aims to provide all the boilerplate SQL you need (DDL, DML, and DCL) via out-of-the-box functionality, which you can configure quickly and concisely. In some cases, there may be SQL that you want or need to run, specific to functionality in your data platform, which dbt does not (yet) offer as a built-in feature. In those cases, you can write the exact SQL you need, using dbt's compilation context, and pass it into a pre-
or post-
hook to run before or after your model, seed, or snapshot.
The render method
The .render()
method is generally used to resolve or evaluate Jinja expressions (such as {{ source(...) }}
) during runtime.
When using the --empty flag
, dbt may skip processing ref()
or source()
for optimization. To avoid compilation errors and to explicitly tell dbt to process a specific relation (ref()
or source()
), use the .render()
method in your model file. For example:
{{ config(
pre_hook = [
"alter external table {{ source('sys', 'customers').render() }} refresh"
]
Examples
[Redshift] Unload one model to S3
{{ config(
post_hook = "unload ('select from {{ this }}') to 's3:/bucket_name/{{ this }}"
) }}
select ...
[Apache Spark] Analyze tables after creation
models:
jaffle_shop: # this is the project name
marts:
finance:
+post-hook:
# this can be a list
- "analyze table {{ this }} compute statistics for all columns"
# or call a macro instead
- "{{ analyze_table() }}"
Additional examples
We've compiled some more in-depth examples here.
Usage notes
Hooks are cumulative
If you define hooks in both your dbt_project.yml
and in the config
block of a model, both sets of hooks will be applied to your model.
Execution ordering
If multiple instances of any hooks are defined, dbt will run each hook using the following ordering:
- Hooks from dependent packages will be run before hooks in the active package.
- Hooks defined within the model itself will be run after hooks defined in
dbt_project.yml
. - Hooks within a given context will be run in the order in which they are defined.