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

make native env rendering opt-in #2618

Merged
merged 3 commits into from
Jul 8, 2020
Merged

Conversation

beckjake
Copy link
Contributor

@beckjake beckjake commented Jul 7, 2020

resolves #2612

Description

Add as_number, as_native, and as_bool filters, which call literal_eval and (for number/bool) ensure the output type is valid.

The default behavior of get_rendered is to return whatever the input value is, which preserves expected behavior with Relations. Multiple nodes are converted to text. The as_text filter still calls str() on the result.

There is a non-obvious breaking change: Port numbers that are set via jinja evaluation (such as via "{{ var(...) }}" and " {{ env_var(...) }}") require the as_number or as_native filter. Fixing this to behave the way it did in 0.16.x is going to be quite annoying, and hologram limitations make it tricky to allow string inputs for ports on that level: You can't define a field encoder whose json_schema is a oneOf, because hologram assumes that the schema for a given field will have a type.

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.

@cla-bot cla-bot bot added the cla:yes label Jul 7, 2020
@jtcohen6 jtcohen6 linked an issue Jul 7, 2020 that may be closed by this pull request
@beckjake beckjake marked this pull request as ready for review July 7, 2020 21:09
Copy link
Contributor

@jtcohen6 jtcohen6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took this for a spin locally. All the new filters work as I expected. The annoying edge cases we previously had to solve with | as_text or triple quoting have magically disappeared.

I'm okay with the breaking change for port, threads, etc. This only started being possible in 0.17.0, right? (#2486) And it will still be possible by way of as_number. I see it as a small burden (and overall net improvement) for the users who set profile configs via Jinja expressions / env vars. We just need to document the hell out of it.

Heroic work on the unit tests.

Copy link
Contributor

@drewbanin drewbanin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this looks really amazing and I'm thrilled with how this turned out! I'll echo Jerco's comment - the tests here are indeed heroic :)

I added a couple of comments/questions - will be happy to be informed that it is late and my eyes are bleary, but otherwise happy to discuss :)

core/dbt/clients/jinja.py Outdated Show resolved Hide resolved
core/dbt/clients/jinja.py Outdated Show resolved Hide resolved
returns("'True'"),
),
(
'''foo: "'{{ true | as_number }}'"''',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is surprising to me - I'd think that as_number would fail because true is not numeric. I imagine I'm missing some quirk here - just curious what it might be!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's because of the quotes. rendering goes down the "".join(...) path because there are multiple "nodes" in the raw render result.

We could definitely make NumberMarker/BoolMarker examine their inputs and error out here if we want. It would potentially be something silly like: try to literal_eval, make sure the result is a number/bool and error out of not, then throw away that result (or store it and expose it to the concatenation function later). It seemed like a lot of complexity of dubious value since things will end up as strings anyway, but I can see why it'd be desirable.

That's all native mode. In text mode, the as_* are all no-ops so they do nothing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok - that's kind of what i figured. The filter in this context is pretty useless anyway given the wrapping quotes outside of the jinja expression. Works for me!

),
(
'''foo:''',
returns('None'),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is surprising to me - why do we return a string 'None' instead of a literal None here? This test differs from my experiences with exercising this PR on the CLI. When I test either of the following values, I get a literal None back instead of a stringy 'None'

foo:
foo: null

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dbt doesn't ever pass non-str values to get_rendered, so this aspect of the test doesn't reflect what dbt will actually do during rendering (see dbt.config.renderer.BaseRenderer.render_value).

I wanted to make sure we did have the underlying behavior documented in unit tests, at least. There are integration tests that exercise the behavior you're talking about.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahhh, that makes total sense too - thanks

beckjake and others added 2 commits July 8, 2020 08:34
Co-authored-by: Drew Banin <drew@fishtownanalytics.com>
@beckjake
Copy link
Contributor Author

beckjake commented Jul 8, 2020

/azp run

@beckjake
Copy link
Contributor Author

beckjake commented Jul 8, 2020

Windows tests aren't running due to an outage: https://status.dev.azure.com/

I think they should be fine though, nothing here is windows-specific.

Copy link
Contributor

@drewbanin drewbanin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work on this one - approved!

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.

0.17.0 regression: Make native env rendering explicit/opt-in
3 participants