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

[Bug] config.get(config.field, default_value) not working properly? #4273

Closed
1 task done
hui-zheng opened this issue Nov 12, 2021 · 10 comments · Fixed by #4297
Closed
1 task done

[Bug] config.get(config.field, default_value) not working properly? #4273

hui-zheng opened this issue Nov 12, 2021 · 10 comments · Fixed by #4297
Assignees
Labels
bug Something isn't working

Comments

@hui-zheng
Copy link

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

for the code below in adapters,

{%- set enable_refresh = config.get('enable_refresh', false) -%}

When the field enable_refresh is not set by model config, a default value false is not used by config.get().
Instead, enable_refresh is set to none.

Expected Behavior

for the code below in adapters,

{%- set enable_refresh = config.get('enable_refresh', false) -%}

When the field enable_refresh is not set by model config, a default value false shall be used. enable_refresh shall be set to `false.

Interestingly, if I use the code below, it works as expected.

{%- set enable_refresh = config.get('enable_refresh', default=false) -%}

Steps To Reproduce

Background

I came across this unexpected behavior when I tried to upgrade BQ materialized_view in dbt-labs-experimental-features to work with dbt 0.21.0

If I have a model materialized_view_A.

Not setting the enable_refresh field in the model config.

{{
  config(
    materialized = "materialized_view",
    partition_by = {
      "field" : "TIMESTAMP_TRUNC(stamp_hourly, DAY)",
      "data_type" : "date"
    },
  )
}}

in bigquery__create_materialized_view_as macro,

    {%- set enable_refresh = config.get('enable_refresh', false) -%}

if you log the value of enable_refresh, you will see it's set to none, which is unexpected.

Now, if you change the code to

    {%- set enable_refresh = config.get('enable_refresh', default=false) -%}

if you log the value of enable_refresh, you will see it's set to false, which is expected.

Relevant log output

No response

Environment

- OS: MacOS
- Python: 3.7
- dbt: 0.21.0

What database are you using dbt with?

bigquery

Additional Context

No response

@hui-zheng hui-zheng added bug Something isn't working triage labels Nov 12, 2021
@hui-zheng hui-zheng changed the title [Bug] config.get('var-name', default_value) not working properly? [Bug] config.get(config.field, default_value) not working properly? Nov 12, 2021
@jtcohen6 jtcohen6 removed the triage label Nov 12, 2021
@jtcohen6
Copy link
Contributor

@hui-zheng You're right! This is a duplicate of a much older issue, one we closed a while ago: #2441.

@gshank It looks like you resolved that issue after v0.20, and I agree we got 90% of the way there, by making config behave much more like a dict, and config.get() a lot more like dict.get(). The subtle difference, raised again in this issue, is that you can provide the default value as the second positional argument for dict.get(). By contrast, default is still not the second positional argument for our config.get()—it's the third, with validator coming in second:

def get(self, name, validator=None, default=None):
return ''

def get(self, name, validator=None, default=None):
to_return = self._lookup(name, default)

I think the resolution to this issue would be as simple as switching the argument order:

    def get(self, name, default=None, validator=None):
        return ''
    def get(self, name, default=None, validator=None):
        to_return = self._lookup(name, default)

That way, config.get('arg1', 'arg2') will be the same as config.get('arg1', default = 'arg2').

This would be a big breaking change. v1 is absolutely the right time to do it; v1 after we've already put out the first release candidate, not as much. Reasons I'm still open to this:

  • We're planning a longer release candidacy, and we're planning to put out a few more RCs before the final
  • Setting default is much more common than setting validator; 100x more common, if I had to guess. (The only place I can think where we use the validator arg is here in a dbt-spark macro, and even there we use it as a keyword argument, since it's a pretty uncommon thing.)

So, what do we think of making this change?


@hui-zheng As an unrelated point: Where did you see enable_refresh? I don't see that code anywhere in our adapter plugins; I think it's in the "experimental feature" for materialized views.

@gshank
Copy link
Contributor

gshank commented Nov 16, 2021

I think the 'get' in the providers is not where config.get() ought to be... that should be the get def in BaseConfig. Let me play with this a bit.

@gshank
Copy link
Contributor

gshank commented Nov 16, 2021

The python dictionary get method only returns the default if the key doesn't exist. So if 'enable_refresh' is set to None in the config, that's what it will return, without regard to the default. I'm thinking that this should work how it does in Python, which it does right now.

@jtcohen6
Copy link
Contributor

@gshank If that's the case, I'd expect:

-- models/any_model.sql
select {{ config.get('made_up_nonexistent_key', 'default_value') }} as col_value

To compile to:

select 'default_value' as col_value

Instead of (current):

select None as col_value

@gshank
Copy link
Contributor

gshank commented Nov 16, 2021

It works in Python. I think Jinja does something to the arguments.

@gshank
Copy link
Contributor

gshank commented Nov 17, 2021

You're right, it's the 'get' method in the RuntimeConfigObject. I didn't realize that we were wrapping that there. What is the 'validator' used for?

@gshank
Copy link
Contributor

gshank commented Nov 17, 2021

My proposal is that we remove the 'validator' keyword argument from 'get' and 'require'. All it does is pass along and execute the passed in function with the value, which can be done in the template if that's wanted. No tests failed. Do you know of anybody who uses it?

@jtcohen6
Copy link
Contributor

Offhand, I know of exactly two places (really one place) where validator is used, in the dbt-spark plugin.

My vote might be to reverse the order of the keyword arguments, but I'd be okay with removing validator entirely if that's cleaner. We'd just need to update dbt-spark, which is fine.

@gshank
Copy link
Contributor

gshank commented Nov 17, 2021

We can leave it in place.

@gshank
Copy link
Contributor

gshank commented Nov 18, 2021

This was fixed with PR #4297. It didn't automatically close because I incorrectly put the ticket number as 4272

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants