-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
[CT-1584] New top level commands: interactive compile #7008
Conversation
Thank you for your pull request! We could not find a changelog entry for this change. For details on how to document a change, see the contributing guide. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Thanks for traversing through the codebase and add this feature!
I did run into one issue that running dbt compile -s customers
(I have a model named that), compiled result was not logged.
The rest of the comments are mostly informational/confirm things.
@@ -42,6 +43,7 @@ | |||
"fail_fast", | |||
"indirect_selection", | |||
"store_failures", | |||
"introspect", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why we want to add introspect here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did it to help a test pass, but it might not be required.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update: removing this doesn't help, so I'll leave it as-is for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean removing it would cause things to fail? This doesn't feel right given that introspect
is only a parameter for compile
task command, and all parameter in this list is defiled both as cli
click group level and a task command level.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Punted into a new ticket: #7156
@@ -29,6 +29,7 @@ | |||
"FULL_REFRESH": False, | |||
"STRICT_MODE": False, | |||
"STORE_FAILURES": False, | |||
"INTROSPECT": True, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we want to figure out a way to remove this section at some point. Just write down what I think, this works before we do that.
@@ -1600,7 +1600,16 @@ message ConcurrencyLineMsg { | |||
ConcurrencyLine data = 2; | |||
} | |||
|
|||
// Skipped Q028 | |||
// Q028 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just curious, what is Q stand for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Node execution, it's not the perfect category, but the best one I could find.
@@ -309,7 +310,7 @@ def skip_result(self, node, message): | |||
|
|||
def compile_and_execute(self, manifest, ctx): | |||
result = None | |||
with self.adapter.connection_for(self.node): | |||
with self.adapter.connection_for(self.node) if get_flags().INTROSPECT else nullcontext(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a user set DBT_INTROSPECT
to False, but we are not running compile/preview command, get_flags().INTROSPECT
will be True
since it is using default value right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the exception of those relative imports, nothing stands out 👍
return "Q028" | ||
|
||
def message(self) -> str: | ||
return f"Compiled node '{self.node_name}' is:\n{self.compiled}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dbeatty10 Does this message make sense, or should I change it to something else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have an example what this message would look like with realistic values?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup:
❯ dbt compile --inline "select * from {{ ref('raw_orders') }}"
...
17:50:59 Compiled node 'inline_query' is:
select * from "jaffle_shop"."main"."raw_orders"
17:50:59 Done.
❯ dbt compile --select stg_payments
...
17:51:27 Compiled node 'stg_payments' is:
with source as (
select * from "jaffle_shop"."main"."raw_payments"
),
renamed as (
select
id as payment_id,
order_id,
payment_method,
-- `amount` is currently stored in cents, so we convert it to dollars
amount / 100 as amount
from source
)
select * from renamed
17:51:27 Done.
def file_exists(*paths): | ||
"""Check if file exists at path""" | ||
return os.path.exists(os.path.join(*paths)) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a problem to solve in this PR, but I wonder why os.path
was used in this module rather than pathlib
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're already using os
in several places instead of pathlib
so wanted to keep the status quo to avoid bringing in a new import.
But I don't feel too strongly either way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, going with the flow make sense in this PR.
Something for us to consider in a refactor down the road though.
core/dbt/task/compile.py
Outdated
@@ -43,19 +43,32 @@ def raise_on_first_error(self): | |||
return True | |||
|
|||
def get_node_selector(self) -> ResourceTypeSelector: | |||
if getattr(self.args, "inline", None): | |||
resource_types = [NodeType.SqlOperation] | |||
elif getattr(self.args, "select", None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will be a behavior change, we can do it in task_end_message if that change is not acceptable.(I don't know whether it is or not)
core/dbt/task/compile.py
Outdated
if getattr(self.args, "inline", None): | ||
resource_types = [NodeType.SqlOperation] | ||
elif getattr(self.args, "select", None): | ||
resource_types = [NodeType.Model] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussed offline yesterday with @aranke @ChenyuLInx:
This is to handle the fact that --select my_model
will also select the tests on my_model
, and we really only want to be compiling one node. The right way to handle this behavior is to turn off "indirect selection," and the cleanest approach there is probably to introduce a new option to turn off indirect selection entirely (--indirect-selection empty
).
Depending on how much work is involved there, we can scope & estimate that as a separate issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a new selection method empty
to only select a node that matches the selector.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did y'all consider any alternative names to empty
? For example, none
feels more intuitive to me, but maybe y'all considered it already.
Adding empty
to the current options would give:
eager
(default) - include ANY test that references the selected nodescautious
- restrict to tests that ONLY refer to selected nodesbuildable
- restrict to tests that ONLY refer to selected nodes (or their ancestors)empty
- don't include any tests
If it is named something like none
, then the list would be this instead:
eager
cautious
buildable
none
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't name a Click option none
without some trickery, since that's a built-in Python type 😞
I anticipate Cloud to be the only people who use this, so didn't give it too much thought.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good over all! Last two questions
def test_select_pass(self, project): | ||
(results, log_output) = run_dbt_and_capture(["compile", "--select", "second_model"]) | ||
assert len(results) == 3 | ||
assert "Compiled node 'second_model' is:" in log_output |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought in this case we would't print the compiled result for second model?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Talked with @jtcohen6 in the office, we should print this out even if we did compile it.
I've included the filtering behavior you mentioned to only print out exact matches for nodes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then --indirect-selection empty
is only to make sure we don't compile test etc? makes sense to me!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it's to only compile the node that is selected and nothing else.
@@ -42,6 +43,7 @@ | |||
"fail_fast", | |||
"indirect_selection", | |||
"store_failures", | |||
"introspect", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean removing it would cause things to fail? This doesn't feel right given that introspect
is only a parameter for compile
task command, and all parameter in this list is defiled both as cli
click group level and a task command level.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with one question
@aranke Do we have an issue opened in the docs.getdbt.com repo for this new feature? If not, then we'd want to fill out the template here. We'd want to add the |
Co-authored-by: Github Build Bot <[email protected]>
@dbeatty10 done, thank you! |
Sure thing @aranke ! Could you also add the I just updated the PR checklist so it's easy to see the linked issue and its status: |
* ct-2198: clean up some type names and uses * CT-2198: Unify constraints and constraints_check properties on columns * Make mypy version consistently 0.981 (#7134) * CT 1808 diff based partial parsing (#6873) * model contracts on models materialized as views (#7120) * first pass * rename tests * fix failing test * changelog * fix functional test * Update core/dbt/parser/base.py * Update core/dbt/parser/schemas.py * Create method for env var deprecation (#7086) * update to allow adapters to change model name resolution in py models (#7115) * update to allow adapters to change model name resolution in py models * add changie * fix newline adds * move quoting into macro * use single quotes * add env DBT_PROJECT_DIR support #6078 (#6659) Co-authored-by: Jeremy Cohen <[email protected]> * Add new index.html and changelog yaml files from dbt-docs (#7141) * Make version configs optional (#7060) * [CT-1584] New top level commands: interactive compile (#7008) Co-authored-by: Github Build Bot <[email protected]> * CT-2198: Add changelog entry * CT-2198: Fix tests which broke after merge * CT-2198: Add explicit validation of constraint types w/ unit test * CT-2198: Move access property, per code review * CT-2198: Remove a redundant macro * CT-1298: Rework constraints to be adapter-generated in Python code * CT-2198: Clarify function name per review --------- Co-authored-by: Gerda Shank <[email protected]> Co-authored-by: Emily Rockman <[email protected]> Co-authored-by: Stu Kilgore <[email protected]> Co-authored-by: colin-rogers-dbt <[email protected]> Co-authored-by: Leo Schick <[email protected]> Co-authored-by: Jeremy Cohen <[email protected]> Co-authored-by: FishtownBuildBot <[email protected]> Co-authored-by: dave-connors-3 <[email protected]> Co-authored-by: Kshitij Aranke <[email protected]> Co-authored-by: Github Build Bot <[email protected]>
Over a year ago in [#7008](https://github.com/dbt-labs/dbt-core/pull/7008/files#diff-c10753a61a1d8f973ec3206206d72b3c5200e41673ab2c6b256f333103eadb8f) the tests in `test_compiler.py` got moved into other testing files. Since then this file has been sitting around empty. It is probably a reasonable time to say goodbye to it.
#9878) * Delete empty `test_compiler.py` file Over a year ago in [#7008](https://github.com/dbt-labs/dbt-core/pull/7008/files#diff-c10753a61a1d8f973ec3206206d72b3c5200e41673ab2c6b256f333103eadb8f) the tests in `test_compiler.py` got moved into other testing files. Since then this file has been sitting around empty. It is probably a reasonable time to say goodbye to it. * Delete empty `searcher.py` file The file `searcher.py` was added, as an empty file, four years ago in [#2312](https://github.com/dbt-labs/dbt-core/pull/2312/files#diff-c8e9e62cf63356f44fe1a2b0272b239d7a650c57911477ed4549b15ee3de16fa). Since then it has never been touched or added to. I'm not sure of the initial purpose of the file as it never contained anything and I have not found any documentation in reference to it. It's safe to say, it can go away.
resolves #6358
Description
Checklist
changie new
to create a changelog entry