dbt-labs / dbt-core

dbt enables data analysts and engineers to transform their data using the same practices that software engineers use to build applications.
https://getdbt.com
Apache License 2.0
9.93k stars 1.63k forks source link

[Bug] unit tests with incremental required mock table to exist #10695

Closed GiorgiModebadzeW closed 1 month ago

GiorgiModebadzeW commented 2 months ago

Is this a new bug in dbt-core?

Current Behavior

When creating unit test for the new incremental table and running it ,it fails if we test model in incremental mode. This is because after mocking "this" dbt before running the unit test tries to check if the table exists and if it does not fails. (For snowflake it runs DESCRIBE statement as the first step)

- input: this 
        # contents of current my_incremental_model
        rows:
          - {event_id: 1, event_time: 2020-01-01}

This is strange and cumbersome because unit tests are supposed to run before the model is run and because those tests can not pass model is never created. This created some kind of deadlock.

currently we need to first create table with (run) and then run unit tests- which defeats purpose of test in the first place and adds overhead for production

Expected Behavior

In the unit tests we already mock this. So there is no particular need why dbt needs to check if the table already exists. (maybe allow bypass?)

- input: this 
        # contents of current my_incremental_model
        rows:
          - {event_id: 1, event_time: 2020-01-01}

Steps To Reproduce

Create incremental table add unit test for the incremental check with

overrides:
      macros:
        is_incremental: true

Run dbt build for this table and unit test will fail Run dbt run for this table and then dbt test or dbt build and unit test will pass.

Relevant log output

09:51:10  
09:51:10    Compilation Error in model my_model (models/data/intermediate/schema/unit_tests/my_unit_test.yml)
  Not able to get columns for unit test 'my_model' from relation db.schema.my_model because the relation doesn't exist

  > in macro get_fixture_sql (macros/unit_test_sql/get_fixture_sql.sql)
  > called by model my_model (models/data/intermediate/schema/unit_tests/my_unit_test.yml)

Environment

- OS: macOS-14.6.1-arm64-arm-64bit
- Python:  3.11.7
- dbt: dbt version: 1.8.5, adapter type: snowflake
11:27:36  adapter version: 1.8.3

Which database adapter are you using with dbt?

snowflake

Additional Context

No response

dbeatty10 commented 2 months ago

Thanks for raising this @GiorgiModebadzeW !

I think the key thing that's happening is that dbt needs to know the data types for each column in your incremental model in order to mock it. So that's why it is running that DESCRIBE statement within Snowflake.

The easiest way to overcome this is to first run your project using the --empty flag (optionally selecting only your incremental models. Something like this:

dbt run --select "config.materialized:incremental" --empty

And after that, then you can do a regular build for that model:

dbt build --select my_model

Could you give that a shot and see if that works when your incremental table doesn't already exist?

GiorgiModebadzeW commented 1 month ago

Thanks @dbeatty10

I think that solves my issue