Skip to main content

Hooks & Operations

Related documentation#

Assumed knowledge#

Getting started#

Effective database administration sometimes requires additional SQL statements to be run, for example:

  • Granting privileges on an table / view
  • Creating UDFs
  • Vacuuming tables on Redshift
  • Creating partitions in Redshift Spectrum external tables
  • Resuming/pausing/resizing warehouses in Snowflake
  • Refreshing a pipe in Snowflake
  • Create a share on Snowflake
  • Cloning a database on Snowflake

dbt provides two different interfaces for you to version control and execute these statements as part of your dbt project — hooks and operations.

Hooks#

Hooks are snippets of SQL that are executed at different times:

  • pre-hook: executed before a model, seed or snapshot is built.
  • post-hook: executed after a model, seed or snapshot is built.
  • on-run-start: executed at the start of dbt run, dbt seed or dbt snapshot
  • on-run-end: executed at the end of dbt run, dbt seed or dbt snapshot

Hooks are defined in your dbt_project.yml file. Pre- and post-hooks can also be defined in a config block.

Here's a minimal example of using hooks to grant privileges. You can find more information in the reference sections for on-run-start and on-run-end hooks and pre-hooks and post-hooks.

dbt_project.yml
on-run-end:  - "grant usage on {{ target.schema }} to role reporter"
models:  +post-hook:    - "grant select on {{ this }} to role reporter"

You can also apply the post-hook to individual models using a config block:

models/<model_name>.sql
{{ config(    post_hook=[      "grant select on {{ this }} to role reporter"    ]) }}
select ...
Calling a macro in a hook

You can also use a macro to bundle up hook logic. Check out some of the examples in the reference sections for on-run-start and on-run-end hooks and pre- and post-hooks,

Operations#

Operations are macros that you can run using the run-operation command command. As such, operations aren't actually a separate resource in your dbt project — they are just a convenient way to invoke a macro without needing to run a model.

Explicitly execute the SQL in an operation

Unlike hooks, you need to explicitly execute a query within a macro, by using either a statement block or a helper macro like the run_query macro macro. Otherwise, dbt will return the query as a string without executing it.

This macro performs a similar action as the above hooks:

macros/grant_select.sql
{% macro grant_select(role) %}{% set sql %}    grant usage on schema {{ target.schema }} to role {{ role }};    grant select on all tables in schema {{ target.schema }} to role {{ role }};    grant select on all views in schema {{ target.schema }} to role {{ role }};{% endset %}
{% do run_query(sql) %}{% do log("Privileges granted", info=True) %}{% endmacro %}

To invoke this macro as an operation, execute dbt run-operation grant_select --args '{role: reporter}'.

$ dbt run-operation grant_select --args '{role: reporter}'Running with dbt=0.16.1Privileges granted

Full usage docs can for the run-operation command can be found here.

Additional examples#

These examples from the community highlight some of the use-cases for hooks and operations!