Skip to content

Commit

Permalink
Enable calling a macro in a pre- or post-hook config in `properties.y…
Browse files Browse the repository at this point in the history
…ml` (#10603) (#10620)

* Tests for calling a macro in a pre- or post-hook config in properties.yml

* Late render pre- and post-hooks configs in properties / schema YAML files

* Changelog entry

(cherry picked from commit 2218140)

Co-authored-by: Doug Beatty <[email protected]>
  • Loading branch information
github-actions[bot] and dbeatty10 authored Aug 27, 2024
1 parent b33faf5 commit 24f840b
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 2 deletions.
6 changes: 6 additions & 0 deletions .changes/unreleased/Fixes-20240824-210903.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Fixes
body: Late render pre- and post-hooks configs in properties / schema YAML files
time: 2024-08-24T21:09:03.252733-06:00
custom:
Author: dbeatty10
Issue: "10603"
9 changes: 9 additions & 0 deletions core/dbt/parser/schema_renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# keyword args are rendered to capture refs in render_test_update.
# Keyword args are finally rendered at compilation time.
# Descriptions are not rendered until 'process_docs'.
# Pre- and post-hooks in configs are late-rendered.
class SchemaYamlRenderer(BaseRenderer):
def __init__(self, context: Dict[str, Any], key: str) -> None:
super().__init__(context)
Expand Down Expand Up @@ -43,6 +44,14 @@ def _is_norender_key(self, keypath: Keypath) -> bool:
if len(keypath) == 2 and keypath[1] in ("tests", "data_tests", "description"):
return True

# pre- and post-hooks
if (
len(keypath) >= 2
and keypath[0] == "config"
and keypath[1] in ("pre_hook", "post_hook")
):
return True

# versions
if len(keypath) == 5 and keypath[4] == "description":
return True
Expand Down
24 changes: 22 additions & 2 deletions tests/functional/adapter/hooks/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@
"""

macros__before_and_after = """
{% macro custom_run_hook(state, target, run_started_at, invocation_id) %}
{% macro custom_run_hook(state, target, run_started_at, invocation_id, table_name="on_run_hook") %}
insert into {{ target.schema }}.on_run_hook (
insert into {{ target.schema }}.{{ table_name }} (
test_state,
target_dbname,
target_host,
Expand Down Expand Up @@ -355,6 +355,26 @@
- not_null
"""

properties__model_hooks = """
version: 2
models:
- name: hooks
config:
pre_hook: "{{ custom_run_hook('start', target, run_started_at, invocation_id, table_name='on_model_hook') }}"
post_hook: "{{ custom_run_hook('end', target, run_started_at, invocation_id, table_name='on_model_hook') }}"
"""

properties__model_hooks_list = """
version: 2
models:
- name: hooks
config:
pre_hook:
- "{{ custom_run_hook('start', target, run_started_at, invocation_id, table_name='on_model_hook') }}"
post_hook:
- "{{ custom_run_hook('end', target, run_started_at, invocation_id, table_name='on_model_hook') }}"
"""

seeds__example_seed_csv = """a,b,c
1,2,3
4,5,6
Expand Down
24 changes: 24 additions & 0 deletions tests/functional/adapter/hooks/test_model_hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@
)

from tests.functional.adapter.hooks.fixtures import (
macros__before_and_after,
models__hooked,
models__hooks,
models__hooks_configured,
models__hooks_error,
models__hooks_kwargs,
models__post,
models__pre,
properties__model_hooks,
properties__model_hooks_list,
properties__seed_models,
properties__test_snapshot_models,
seeds__example_seed_csv,
Expand Down Expand Up @@ -262,6 +265,27 @@ def test_hooks_on_seeds(self, project):
assert len(res) == 1, "Expected exactly one item"


class TestPrePostModelHooksWithMacros(BaseTestPrePost):
@pytest.fixture(scope="class")
def macros(self):
return {"before-and-after.sql": macros__before_and_after}

@pytest.fixture(scope="class")
def models(self):
return {"schema.yml": properties__model_hooks, "hooks.sql": models__hooks}

def test_pre_and_post_run_hooks(self, project, dbt_profile_target):
run_dbt()
self.check_hooks("start", project, dbt_profile_target.get("host", None))
self.check_hooks("end", project, dbt_profile_target.get("host", None))


class TestPrePostModelHooksListWithMacros(TestPrePostModelHooksWithMacros):
@pytest.fixture(scope="class")
def models(self):
return {"schema.yml": properties__model_hooks_list, "hooks.sql": models__hooks}


class TestHooksRefsOnSeeds:
"""
This should not succeed, and raise an explicit error
Expand Down

0 comments on commit 24f840b

Please sign in to comment.