Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable test project hooks, flags.WHICH #4004

Merged
merged 4 commits into from
Oct 18, 2021
Merged

Conversation

jtcohen6
Copy link
Contributor

@jtcohen6 jtcohen6 commented Oct 5, 2021

resolves #3463

Previously

  • dbt test (and only dbt test) would not run on-run-start and on-run-end hooks.

This made sense in a time when test didn't actually create objects in the database, and the main motivation of on-run-end hooks was to run grant statementsm or other object/schema-level resource maintenance.

This carved-out exception has proven painful, though, because the {{ results }} context object, available only in the on-run-end context, contains a lot of valuable metadata (e.g. set of all test statuses/failures) that folks want to log, drop in the database, etc. (See: slack thread)

Change

  • All "building" tasks should run these hooks: run, test, seed, snapshot, i.e. the tasks included by build. (Still excluded: compile, docs generate, list, source freshness, etc.)
  • A new flag, WHICH, that gives users a way to run a specific hook (or not) depending on the current ask
{% macro my_test_end_hook() %}

  {% do log(flags.WHICH, info = true) %}
  {% if flags.WHICH == 'test' %}
    -- do something test-specific with {{ results }}
  {% else %}
    select 1 as id
  {% endif %}

{% endmacro %}
# dbt_project.yml
on-run-end:
  - "{{ my_test_end_hook() }}"

Commentary & questions

  • I didn't previously have this on our v1.0 list, but it's a pretty simple and significant change, and I think it's one we should make. I also think it's less critical than before, with the advent of dbt build as the task to do it all.
  • It feels a little uncomfortable that we expose the entire dbt.core.flags module to the Jinja context! Would we be better off exposing just a key-value dict containing all user-exposed flags/args?
  • It would be very easy to support Add a "full run" indicator to Jinja context #2253 (comment) as well by adding flags.SELECT, flags.EXCLUDE, flags.SELECTOR. Or should we instead construct a generic args object that has it all?
  • We'll need to document really clearly that all of these flags values are expected to change at execution time, in any invocation, so users must not use these as inputs to parse-time values (ref/source + configs) with partial parsing enabled—otherwise bad things will happen. It's also just not a good pattern! In my dream of dreams, a world where we've truly separate parsing from execution, these flags should return None at parse time. Is that a worthy thing to aspire for?

Checklist

  • I have signed the CLA
  • I have run this code in development and it appears to resolve the stated issue
  • This PR includes tests, or tests are not required/relevant for this PR
  • I have updated the CHANGELOG.md and added information about my change to the "dbt next" section.

@jtcohen6 jtcohen6 requested a review from gshank October 5, 2021 08:59
@cla-bot cla-bot bot added the cla:yes label Oct 5, 2021
@jtcohen6
Copy link
Contributor Author

jtcohen6 commented Oct 5, 2021

@gshank I'd appreciate your thoughts here, given your recent work on the flags module, and around parsing more generally. This isn't something we definitely need to do, but if we're going to do it, the change to the test task in particular feels like one we should make ahead of v1.0.

@jtcohen6 jtcohen6 force-pushed the enable-test-project-hooks branch from de77e24 to ead4ba1 Compare October 5, 2021 09:47
@gshank
Copy link
Contributor

gshank commented Oct 5, 2021

I agree that exporting the entire flags module feels wrong. We probably want to make a cleaner break between things that we support people looking up in jinja and things that are just for internal use. Also might want to prevent people from setting some of them directly. There is a dictionary available from get_flag_dict, but it doesn't have the subcommand flags in it.

The args object has gotten to act like a global setting store, but I'm not certain how I feel about that. We've expanded its use as a cli arg store quite past the original purpose, but it's just a Namespace class at the moment, and there's no behavior associated with it. It might be better to create an internal Settings object and copy the relevant args into it. We could have a read-only dictionary version of allowed settings available to jinja?

The flags/args/settings discussion aside, enabling this for tests seems like a good 1.0 feature.

@jtcohen6
Copy link
Contributor Author

jtcohen6 commented Oct 6, 2021

It might be better to create an internal Settings object and copy the relevant args into it. We could have a read-only dictionary version of allowed settings available to jinja?

@gshank I strongly agree with this. I'd be very comfortable with explicitly enumerating exactly which args/flags/settings should be accessible to the Jinja context. How tricky do you think this might be to implement?

Separately, would there be a way that we could offer backwards compatibility for folks who are used to reading a specific flag value into the Jinja context as flags.FLAG? Perhaps substituting a limited module that just redirects to the read-only dictionary? If that has to be a breaking change without backwards compatibility, it's not the end of the world; I think our built-in macros are the main consumers of flags.

@gshank
Copy link
Contributor

gshank commented Oct 8, 2021

I think there would be a bunch of trivial changes, so a fair number of lines of code to change, but not hard and mostly greppable. I'm thinking we'd replace internal use of flags entirely with a Settings object (probably a global one, kind of like the current adapter) and leave the flags module for compatibility for users. We kind of overuse the current args in a number of places so it's possible that would be a bit tricky to tease apart. The RPC server is going to be changing soon, so we might want to consult that team about what would work for them too.

@jtcohen6
Copy link
Contributor Author

I left it as a TODO to rework the flags module, and expose an object that provides read-only access to users in the Jinja context. That's something we could hit if we have time ahead of v1.

@jtcohen6 jtcohen6 force-pushed the enable-test-project-hooks branch from ead4ba1 to caf0318 Compare October 14, 2021 09:47
@jtcohen6 jtcohen6 force-pushed the enable-test-project-hooks branch from caf0318 to a3a72ce Compare October 15, 2021 08:43
@jtcohen6 jtcohen6 force-pushed the enable-test-project-hooks branch from a3a72ce to ff6a443 Compare October 18, 2021 08:31
@jtcohen6 jtcohen6 merged commit 4bda8c8 into main Oct 18, 2021
@jtcohen6 jtcohen6 deleted the enable-test-project-hooks branch October 18, 2021 08:50
iknox-fa pushed a commit that referenced this pull request Feb 8, 2022
* Turn on project hooks test task

* Add flags.WHICH

* Rm unused env vars (RPC)

* Add changelog entry

automatic commit by git-black, original commits:
  4bda8c8
mirnawong1 added a commit to dbt-labs/docs.getdbt.com that referenced this pull request Apr 27, 2023
…mentation (#3246)

## What are you changing in this pull request and why?
The `on-run-start` and `on-run-end` hooks are documented in the
[build/hooks-operations](https://docs.getdbt.com/docs/build/hooks-operations)
page, but it doesn't reflect that they run after `dbt test` (following
[dbt-core#4004](dbt-labs/dbt-core#4004)):


https://github.com/dbt-labs/docs.getdbt.com/blob/efe200c0ba5c4f87641d82b1d7bc9a3a83b20696/website/docs/docs/build/hooks-operations.md?plain=1#L35-L36

This PR will add `dbt test` to the list in both of these bullets


## Checklist
- [x] Review the [Content style
guide](https://github.com/dbt-labs/docs.getdbt.com/blob/current/contributing/content-style-guide.md)
and [About
versioning](https://github.com/dbt-labs/docs.getdbt.com/blob/current/contributing/single-sourcing-content.md#adding-a-new-version)
so my content adheres to these guidelines.
- [ ] Add a checklist item for anything that needs to happen before this
PR is merged, such as "needs technical review" or "change base branch."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature: More granular on-start and on-end hooks
2 participants