How can i call a test like a macro

hi, everyone:

I’m using dbt in my work, it’s great. But I have no idea on something: I defined some test, and I want to call them after a model running to make sure that the result of model if correct, or the data quality is good. If I run dbt test, it will run only after all the models generated, and will cause some problem if some model’s quality is bad.
So i want call the test from post-hook like calling a macro. How can i do that?

Thanks a lot for any suggestion!

You can also select your model in the test command using dbt test --select model_name.
if you wanna run the test macro in post hook , add the post-hook to the config function in your model.sql file as shown below

{{ config(
  post_hook = " model_test_macro(arg1,arg2)"
) }}

Thanks a lot, I will try it later!

Running a test in a post-hook will still mean that the model has been built and cause any issues you were concerned about.

Running a test macro in a post-hook is not a supported configuration - I think it will run the test sql, but it won’t do anything with the results if the test fails.

The recommended way to avoid deploying invalid datasets is to run a blue-green deployment, where you build everything but only switch out the tables if the tests have passed.

I test it, but it fails.

I write a model , and add these code:
{{ config( post_hook="{{ unique('t1', 'id') }}") }}
When I do dbt run, I get:
00:30:43 Running with dbt=1.4.5 00:30:43 Found 1 model, 0 tests, 0 snapshots, 0 analyses, 292 macros, 0 operations, 0 seed files, 0 sources, 0 exposures, 0 metrics 00:30:43 00:30:44 Concurrency: 1 threads (target='dev') 00:30:44 00:30:44 1 of 1 START sql view model main.t2 ............................................ [RUN] 00:30:44 1 of 1 ERROR creating sql view model main.t2 ................................... [ERROR in 0.04s] 00:30:44 00:30:44 Finished running 1 view model in 0 hours 0 minutes and 0.11 seconds (0.11s). 00:30:44 00:30:44 Completed with 1 error and 0 warnings: 00:30:44 00:30:44 Compilation Error in model t2 (models\example\t2.sql) 00:30:44 'unique' is undefined 00:30:44 00:30:44 > in macro run_hooks (macros\materializations\hooks.sql) 00:30:44 > called by macro materialization_view_sqlite (macros\materializations\view\view.sql) 00:30:44 > called by model t2 (models\example\t2.sql). This can happen when calling a macro that does not exist. Check for typos and/or install package dependencies with "dbt deps". 00:30:44 00:30:44 Done. PASS=0 WARN=0 ERROR=1 SKIP=0 TOTAL=1

I think the “unique” test can not be treated as a macro.

Thank for your replay!

I want do a quality check when a model was built. In some cases, it’s important to have a check during a dbt job. For example, I can make sure that all the data flowing to the next node are unique, if something wrong, I can take an action.
So it’s a check during a run.

I can make a call to macro, but I want to use the test defined in th project.

Thanks a lot!

you can write a macro and call the macro in model pre-hook.
the macro should have your test logic,
if your the test logic passes then return none else raise an exception.

@joellabes i hope this would work

It can work. But using the pre-defined test logic can provide a unified method, and all the test in dbt_utils, dbt_expectations(and some other packages) can be used. :slight_smile:

If you use dbt build, it will skip any downstream nodes when a test fails, which will prevent data which doesn’t meet your expectations from flowing further

So what I want to do is doing test just after the model was built. If the build job was finished with no error, but the data produced has some error(espcially logic error), the whole job will not fire an error event. Here, we can do some check by specifying the test marco.

BTW, I think the perfect way is to include some(certern) test in DAG.

Thanks

just like “post_test” or “pre_test” :grinning:

This is what dbt build does. When the model is built, it runs any tests attached to it.

Are you saying this is what you think happens, or what you want to happen? If a logic error is detected by a model’s test, then models that depend on the first model will not run, and the whole job will have an error event (when everything else has completed).

If you want the job to not fire an error event when it encounters an error, that is not possible.

You might want to read/weigh in on this discussion: Provide option to allow tests to be ran before a model's data is updated · dbt-labs/dbt-core · Discussion #5687 · GitHub

Yes! The discussion is what I want, and give all the details!

Thanks again for your help!

A suggestion: the discussion can be published as a document or a blog post. :slight_smile:

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.