Hooks and Operations

Hooks and operations in dex let you run custom logic before or after certain actions during the build process. They're useful for automating side effects such as permission grants, logging, notifications, or downstream system triggers.

Hooks are declared inside your models or macros using the config() block, and they’re executed as part of your model’s lifecycle. Operations, on the other hand, are standalone SQL or Python scripts that can be triggered manually or as part of a Flow.

Both features help you extend dex beyond transformation logic—adding automation and control to your data platform.

What Are Hooks?

Hooks are commands that run automatically at specific moments during model execution. dex supports two hook types:

  • pre-hook: runs before the model executes

  • post-hook: runs after the model finishes

Hooks are often used to:

  • Grant access to specific roles after a model is created

  • Log or audit model execution

  • Clean up intermediate tables or update metadata

Example: Post-Hook to Grant Permissions

{{ config(
    materialized='table',
    post_hook=[
      "grant select on {{ this }} to role analytics"
    ]
) }}

select *
from {{ ref('customer_orders') }}

In this example, once the model is created or updated, it will automatically grant SELECT permissions to the analytics role.

You can define multiple hooks by passing a list of SQL strings or macros.

When Hooks Run

Hooks run as part of a model’s lifecycle and follow these phases:

  1. pre-hook: runs before model logic is executed

  2. Model logic is compiled and executed

  3. post-hook: runs after the model finishes successfully

Hooks can be used with models, snapshots, seeds, and other resources.

If a hook fails, the model run may fail as well

Operations

Operations in dex are standalone SQL or Python scripts that you can execute independently of models. They’re useful for:

  • Maintenance tasks

  • Triggers and notifications

  • One-off administrative jobs

  • Managing external systems

Operations can be:

  • Manually executed from the UI

  • Included in Flows

  • Parameterized using Jinja and environment variables

Example SQL operation

-- operations/grant_access.sql

grant select on schema reporting to role finance

You can then trigger this operation manually or schedule it as part of a Flow.

File Structure Example

models/
  └── core/
      └── revenue.sql

operations/
  └── permissions/
      └── grant_analytics_access.sql
  └── maintenance/
      └── refresh_indexes.sql

Best Practices

  • Use post-hooks for controlled side effects like permissions or metadata updates

  • Keep hook logic idempotent—make sure it won’t break if run multiple times

  • Group operations by purpose (e.g. permissions/, maintenance/, sync/)

  • Avoid putting complex business logic in hooks—prefer models and macros instead

  • Test hooks in non-production environments before rollout

Last updated

Was this helpful?