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

Create adapter.dispatch #2679

Merged
merged 4 commits into from
Aug 4, 2020
Merged

Conversation

beckjake
Copy link
Contributor

@beckjake beckjake commented Aug 3, 2020

resolves #2302 (the rest of it)

Description

This is a follow-up to #2675.

This PR adds the adapter.dispatch described in #2302, and marked adapter_macro as deprecated. This is a pretty straightforward PR. The dispatch method happens on the "database wrapper" rather than the actual adapter, as adapters themselves don't know about manifests/namespacing. The adapter_macro context method now calls into dispatch.

I had to massage some of the error messaging, but I think it's ok.

A large part of this PR is just converting adapter_macro(foo, *args, **kwargs) calls into adapter.dispatch(foo)(*args, **kwargs).

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.

Added tests
Added deprecation warning + tests
@beckjake beckjake requested review from gshank, kwigley and jtcohen6 August 3, 2020 17:24
@cla-bot cla-bot bot added the cla:yes label Aug 3, 2020
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.

This works as expected, and it returns sensible messages when I do things like:

  • use adapter_macro as before (with deprecation warning)
  • use adapter_macro with no adequate implementation (missing default__)
  • use adapter.dispatch with no adequate implementation (missing default__)
  • lazily try to swap adapter_macro('my_package.my_macro') --> adapter.dispatch('my_package.my_macro') instead of realizing I should use adapter.dispatch('my_macro', packages = ['my_package'])
    • post-realization, I first instinctively wrote adapter.dispatch('my_macro', packages = 'my_package'), which dbt coerced to [m,y,_,p,a,c,k,a,g,e]. I think that's ok. I'll call out that packages must be a list in documentation, and the error returned is pretty obvious.

I went so far as to play around with "overriding" dbt_utils macros from a separate package by passing a var into the packages arg of dispatch, as outlined in #2302. It's a bit finicky only because of how vars work with packages. Most importantly, it works.

except CompilationException as exc:
raise CompilationException(
f'In adapter_macro: {exc.msg}\n'
f" Original name: '{name}'",
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we make this the full original macro name, including the package namespace if it included a .?

attempts = []

for package_name in search_packages:
for prefix in self._get_adapter_macro_prefixes():
Copy link
Contributor

Choose a reason for hiding this comment

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

Am I right in understanding that the order of preference is packages > adapter specificity? So e.g. a dispatch with two packages running on Postgres would look for:

  1. packages[0], postgres_
  2. packages[0], default__
  3. packages[1], postgres__
  4. packages[1], default__

Per the comment above, someday we may make it so that running on Redshift looks for:

  1. packages[0], redshift__
  2. packages[0], postgres__
  3. packages[0], default__
  4. packages[1], redshift__
    ...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. We can of course swap this order if we want, but it seemed more correct to me to go by package first - looking at the example in #2302, it seems that you'd want your custom macro to tell dbt-utils "search this other package first and then fall back to dbt-utils if it's not there". This provides a nice escape hatch for issues where "dbt-utils has an implementation of a macro that doesn't work for me because of my obscure workflow". Or even just a bug!

Copy link
Contributor

Choose a reason for hiding this comment

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

Agree! Give first priority to the place where end users have the most control, let them override default__ or do anything they want. Just wanted to make sure I had this down before writing docs

@beckjake
Copy link
Contributor Author

beckjake commented Aug 4, 2020

post-realization, I first instinctively wrote adapter.dispatch('my_macro', packages = 'my_package'), which dbt coerced to [m,y,_,p,a,c,k,a,g,e]. I think that's ok. I'll call out that packages must be a list in documentation, and the error returned is pretty obvious.

I think we should probably make sure the parameter isn't a list. This is an easy mistake to make and python doesn't have the decency to throw a type error.

@beckjake beckjake mentioned this pull request Aug 4, 2020
4 tasks
Copy link
Contributor

@kwigley kwigley left a comment

Choose a reason for hiding this comment

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

Looks good to me!

@beckjake beckjake merged commit 1ece515 into dev/marian-anderson Aug 4, 2020
@beckjake beckjake deleted the feature/adapter-dispatch branch August 4, 2020 18:01
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.

Port adapter_macro implementation into Python
3 participants