-
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
fix #7502: write run_results.json for run operation #7655
Changes from all commits
a500e37
17d5e0d
252d4bc
8ce74ff
99c4523
f50328f
ac5e0c0
c3163d8
c38d618
e9cfe93
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
kind: Fixes | ||
body: write run_results.json for run operation | ||
time: 2023-05-22T13:29:24.182612-07:00 | ||
custom: | ||
Author: aranke | ||
Issue: "7502" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,25 @@ | ||
from datetime import datetime | ||
import os | ||
import threading | ||
import traceback | ||
from datetime import datetime | ||
|
||
import agate | ||
|
||
from .base import ConfiguredTask | ||
|
||
import dbt.exceptions | ||
from dbt.adapters.factory import get_adapter | ||
from dbt.contracts.results import RunOperationResultsArtifact | ||
from dbt.contracts.files import FileHash | ||
from dbt.contracts.graph.nodes import HookNode | ||
from dbt.contracts.results import RunResultsArtifact, RunResult, RunStatus, TimingInfo | ||
from dbt.events.functions import fire_event | ||
from dbt.events.types import ( | ||
RunningOperationCaughtError, | ||
RunningOperationUncaughtError, | ||
LogDebugStackTrace, | ||
) | ||
from dbt.node_types import NodeType | ||
from dbt.task.base import ConfiguredTask | ||
|
||
RESULT_FILE_NAME = "run_results.json" | ||
|
||
|
||
class RunOperationTask(ConfiguredTask): | ||
|
@@ -22,7 +28,7 @@ def _get_macro_parts(self): | |
if "." in macro_name: | ||
package_name, macro_name = macro_name.split(".", 1) | ||
else: | ||
package_name = None | ||
package_name = self.config.project_name | ||
|
||
return package_name, macro_name | ||
|
||
|
@@ -40,7 +46,7 @@ def _run_unsafe(self) -> agate.Table: | |
|
||
return res | ||
|
||
def run(self) -> RunOperationResultsArtifact: | ||
def run(self) -> RunResultsArtifact: | ||
start = datetime.utcnow() | ||
self.compile_manifest() | ||
try: | ||
|
@@ -56,11 +62,51 @@ def run(self) -> RunOperationResultsArtifact: | |
else: | ||
success = True | ||
end = datetime.utcnow() | ||
return RunOperationResultsArtifact.from_success( | ||
|
||
package_name, macro_name = self._get_macro_parts() | ||
fqn = [NodeType.Operation, package_name, macro_name] | ||
unique_id = ".".join(fqn) | ||
|
||
run_result = RunResult( | ||
adapter_response={}, | ||
status=RunStatus.Success if success else RunStatus.Error, | ||
execution_time=(end - start).total_seconds(), | ||
failures=0 if success else 1, | ||
message=None, | ||
node=HookNode( | ||
alias=macro_name, | ||
checksum=FileHash.from_contents(unique_id), | ||
database=self.config.credentials.database, | ||
schema=self.config.credentials.schema, | ||
resource_type=NodeType.Operation, | ||
fqn=fqn, | ||
name=macro_name, | ||
unique_id=unique_id, | ||
package_name=package_name, | ||
path="", | ||
original_file_path="", | ||
), | ||
thread_id=threading.current_thread().name, | ||
timing=[TimingInfo(name=macro_name, started_at=start, completed_at=end)], | ||
) | ||
|
||
results = RunResultsArtifact.from_execution_results( | ||
generated_at=end, | ||
elapsed_time=(end - start).total_seconds(), | ||
success=success, | ||
args={ | ||
k: v | ||
for k, v in self.args.__dict__.items() | ||
if k.islower() and type(v) in (str, int, float, bool, list, dict) | ||
}, | ||
results=[run_result], | ||
) | ||
|
||
result_path = os.path.join(self.config.target_path, RESULT_FILE_NAME) | ||
|
||
if self.args.write_json: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did we settle on lower case or upper case? I remember the other place used There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It gets written to both, I saw lowercase in several places, so just ran with it. |
||
results.write(result_path) | ||
|
||
return results | ||
|
||
def interpret_results(self, results): | ||
return results.success | ||
return results.results[0].status == RunStatus.Success |
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 am assuming you don't need to define the name here? the
RESULT_FILE_NAME
should be defined somewhere 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.
Nope, they're defined inline:
dbt-core/core/dbt/task/runnable.py
Line 58 in dffbb6a
dbt-core/core/dbt/task/freshness.py
Line 30 in dffbb6a
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.
Maybe we should put those constants in base task file or somewhere and import them in other tasks so the string is only being defined once. I will leave it to you to either do it here, a follow up PR, or not do anything.
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'll leave it as-is for now.