dvt-core 1.11.0b4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of dvt-core might be problematic. Click here for more details.
- dvt/__init__.py +7 -0
- dvt/_pydantic_shim.py +26 -0
- dvt/adapters/__init__.py +16 -0
- dvt/adapters/multi_adapter_manager.py +268 -0
- dvt/artifacts/__init__.py +0 -0
- dvt/artifacts/exceptions/__init__.py +1 -0
- dvt/artifacts/exceptions/schemas.py +31 -0
- dvt/artifacts/resources/__init__.py +116 -0
- dvt/artifacts/resources/base.py +68 -0
- dvt/artifacts/resources/types.py +93 -0
- dvt/artifacts/resources/v1/analysis.py +10 -0
- dvt/artifacts/resources/v1/catalog.py +23 -0
- dvt/artifacts/resources/v1/components.py +275 -0
- dvt/artifacts/resources/v1/config.py +282 -0
- dvt/artifacts/resources/v1/documentation.py +11 -0
- dvt/artifacts/resources/v1/exposure.py +52 -0
- dvt/artifacts/resources/v1/function.py +53 -0
- dvt/artifacts/resources/v1/generic_test.py +32 -0
- dvt/artifacts/resources/v1/group.py +22 -0
- dvt/artifacts/resources/v1/hook.py +11 -0
- dvt/artifacts/resources/v1/macro.py +30 -0
- dvt/artifacts/resources/v1/metric.py +173 -0
- dvt/artifacts/resources/v1/model.py +146 -0
- dvt/artifacts/resources/v1/owner.py +10 -0
- dvt/artifacts/resources/v1/saved_query.py +112 -0
- dvt/artifacts/resources/v1/seed.py +42 -0
- dvt/artifacts/resources/v1/semantic_layer_components.py +72 -0
- dvt/artifacts/resources/v1/semantic_model.py +315 -0
- dvt/artifacts/resources/v1/singular_test.py +14 -0
- dvt/artifacts/resources/v1/snapshot.py +92 -0
- dvt/artifacts/resources/v1/source_definition.py +85 -0
- dvt/artifacts/resources/v1/sql_operation.py +10 -0
- dvt/artifacts/resources/v1/unit_test_definition.py +78 -0
- dvt/artifacts/schemas/__init__.py +0 -0
- dvt/artifacts/schemas/base.py +191 -0
- dvt/artifacts/schemas/batch_results.py +24 -0
- dvt/artifacts/schemas/catalog/__init__.py +12 -0
- dvt/artifacts/schemas/catalog/v1/__init__.py +0 -0
- dvt/artifacts/schemas/catalog/v1/catalog.py +60 -0
- dvt/artifacts/schemas/freshness/__init__.py +1 -0
- dvt/artifacts/schemas/freshness/v3/__init__.py +0 -0
- dvt/artifacts/schemas/freshness/v3/freshness.py +159 -0
- dvt/artifacts/schemas/manifest/__init__.py +2 -0
- dvt/artifacts/schemas/manifest/v12/__init__.py +0 -0
- dvt/artifacts/schemas/manifest/v12/manifest.py +212 -0
- dvt/artifacts/schemas/results.py +148 -0
- dvt/artifacts/schemas/run/__init__.py +2 -0
- dvt/artifacts/schemas/run/v5/__init__.py +0 -0
- dvt/artifacts/schemas/run/v5/run.py +184 -0
- dvt/artifacts/schemas/upgrades/__init__.py +4 -0
- dvt/artifacts/schemas/upgrades/upgrade_manifest.py +174 -0
- dvt/artifacts/schemas/upgrades/upgrade_manifest_dbt_version.py +2 -0
- dvt/artifacts/utils/validation.py +153 -0
- dvt/cli/__init__.py +1 -0
- dvt/cli/context.py +16 -0
- dvt/cli/exceptions.py +56 -0
- dvt/cli/flags.py +558 -0
- dvt/cli/main.py +971 -0
- dvt/cli/option_types.py +121 -0
- dvt/cli/options.py +79 -0
- dvt/cli/params.py +803 -0
- dvt/cli/requires.py +478 -0
- dvt/cli/resolvers.py +32 -0
- dvt/cli/types.py +40 -0
- dvt/clients/__init__.py +0 -0
- dvt/clients/checked_load.py +82 -0
- dvt/clients/git.py +164 -0
- dvt/clients/jinja.py +206 -0
- dvt/clients/jinja_static.py +245 -0
- dvt/clients/registry.py +192 -0
- dvt/clients/yaml_helper.py +68 -0
- dvt/compilation.py +833 -0
- dvt/compute/__init__.py +26 -0
- dvt/compute/base.py +288 -0
- dvt/compute/engines/__init__.py +13 -0
- dvt/compute/engines/duckdb_engine.py +368 -0
- dvt/compute/engines/spark_engine.py +273 -0
- dvt/compute/query_analyzer.py +212 -0
- dvt/compute/router.py +483 -0
- dvt/config/__init__.py +4 -0
- dvt/config/catalogs.py +95 -0
- dvt/config/compute_config.py +406 -0
- dvt/config/profile.py +411 -0
- dvt/config/profiles_v2.py +464 -0
- dvt/config/project.py +893 -0
- dvt/config/renderer.py +232 -0
- dvt/config/runtime.py +491 -0
- dvt/config/selectors.py +209 -0
- dvt/config/utils.py +78 -0
- dvt/connectors/.gitignore +6 -0
- dvt/connectors/README.md +306 -0
- dvt/connectors/catalog.yml +217 -0
- dvt/connectors/download_connectors.py +300 -0
- dvt/constants.py +29 -0
- dvt/context/__init__.py +0 -0
- dvt/context/base.py +746 -0
- dvt/context/configured.py +136 -0
- dvt/context/context_config.py +350 -0
- dvt/context/docs.py +82 -0
- dvt/context/exceptions_jinja.py +179 -0
- dvt/context/macro_resolver.py +195 -0
- dvt/context/macros.py +171 -0
- dvt/context/manifest.py +73 -0
- dvt/context/providers.py +2198 -0
- dvt/context/query_header.py +14 -0
- dvt/context/secret.py +59 -0
- dvt/context/target.py +74 -0
- dvt/contracts/__init__.py +0 -0
- dvt/contracts/files.py +413 -0
- dvt/contracts/graph/__init__.py +0 -0
- dvt/contracts/graph/manifest.py +1904 -0
- dvt/contracts/graph/metrics.py +98 -0
- dvt/contracts/graph/model_config.py +71 -0
- dvt/contracts/graph/node_args.py +42 -0
- dvt/contracts/graph/nodes.py +1806 -0
- dvt/contracts/graph/semantic_manifest.py +233 -0
- dvt/contracts/graph/unparsed.py +812 -0
- dvt/contracts/project.py +417 -0
- dvt/contracts/results.py +53 -0
- dvt/contracts/selection.py +23 -0
- dvt/contracts/sql.py +86 -0
- dvt/contracts/state.py +69 -0
- dvt/contracts/util.py +46 -0
- dvt/deprecations.py +347 -0
- dvt/deps/__init__.py +0 -0
- dvt/deps/base.py +153 -0
- dvt/deps/git.py +196 -0
- dvt/deps/local.py +80 -0
- dvt/deps/registry.py +131 -0
- dvt/deps/resolver.py +149 -0
- dvt/deps/tarball.py +121 -0
- dvt/docs/source/_ext/dbt_click.py +118 -0
- dvt/docs/source/conf.py +32 -0
- dvt/env_vars.py +64 -0
- dvt/event_time/event_time.py +40 -0
- dvt/event_time/sample_window.py +60 -0
- dvt/events/__init__.py +16 -0
- dvt/events/base_types.py +37 -0
- dvt/events/core_types_pb2.py +2 -0
- dvt/events/logging.py +109 -0
- dvt/events/types.py +2534 -0
- dvt/exceptions.py +1487 -0
- dvt/flags.py +89 -0
- dvt/graph/__init__.py +11 -0
- dvt/graph/cli.py +248 -0
- dvt/graph/graph.py +172 -0
- dvt/graph/queue.py +213 -0
- dvt/graph/selector.py +375 -0
- dvt/graph/selector_methods.py +976 -0
- dvt/graph/selector_spec.py +223 -0
- dvt/graph/thread_pool.py +18 -0
- dvt/hooks.py +21 -0
- dvt/include/README.md +49 -0
- dvt/include/__init__.py +3 -0
- dvt/include/global_project.py +4 -0
- dvt/include/starter_project/.gitignore +4 -0
- dvt/include/starter_project/README.md +15 -0
- dvt/include/starter_project/__init__.py +3 -0
- dvt/include/starter_project/analyses/.gitkeep +0 -0
- dvt/include/starter_project/dvt_project.yml +36 -0
- dvt/include/starter_project/macros/.gitkeep +0 -0
- dvt/include/starter_project/models/example/my_first_dbt_model.sql +27 -0
- dvt/include/starter_project/models/example/my_second_dbt_model.sql +6 -0
- dvt/include/starter_project/models/example/schema.yml +21 -0
- dvt/include/starter_project/seeds/.gitkeep +0 -0
- dvt/include/starter_project/snapshots/.gitkeep +0 -0
- dvt/include/starter_project/tests/.gitkeep +0 -0
- dvt/internal_deprecations.py +27 -0
- dvt/jsonschemas/__init__.py +3 -0
- dvt/jsonschemas/jsonschemas.py +309 -0
- dvt/jsonschemas/project/0.0.110.json +4717 -0
- dvt/jsonschemas/project/0.0.85.json +2015 -0
- dvt/jsonschemas/resources/0.0.110.json +2636 -0
- dvt/jsonschemas/resources/0.0.85.json +2536 -0
- dvt/jsonschemas/resources/latest.json +6773 -0
- dvt/links.py +4 -0
- dvt/materializations/__init__.py +0 -0
- dvt/materializations/incremental/__init__.py +0 -0
- dvt/materializations/incremental/microbatch.py +235 -0
- dvt/mp_context.py +8 -0
- dvt/node_types.py +37 -0
- dvt/parser/__init__.py +23 -0
- dvt/parser/analysis.py +21 -0
- dvt/parser/base.py +549 -0
- dvt/parser/common.py +267 -0
- dvt/parser/docs.py +52 -0
- dvt/parser/fixtures.py +51 -0
- dvt/parser/functions.py +30 -0
- dvt/parser/generic_test.py +100 -0
- dvt/parser/generic_test_builders.py +334 -0
- dvt/parser/hooks.py +119 -0
- dvt/parser/macros.py +137 -0
- dvt/parser/manifest.py +2204 -0
- dvt/parser/models.py +574 -0
- dvt/parser/partial.py +1179 -0
- dvt/parser/read_files.py +445 -0
- dvt/parser/schema_generic_tests.py +423 -0
- dvt/parser/schema_renderer.py +111 -0
- dvt/parser/schema_yaml_readers.py +936 -0
- dvt/parser/schemas.py +1467 -0
- dvt/parser/search.py +149 -0
- dvt/parser/seeds.py +28 -0
- dvt/parser/singular_test.py +20 -0
- dvt/parser/snapshots.py +44 -0
- dvt/parser/sources.py +557 -0
- dvt/parser/sql.py +63 -0
- dvt/parser/unit_tests.py +622 -0
- dvt/plugins/__init__.py +20 -0
- dvt/plugins/contracts.py +10 -0
- dvt/plugins/exceptions.py +2 -0
- dvt/plugins/manager.py +164 -0
- dvt/plugins/manifest.py +21 -0
- dvt/profiler.py +20 -0
- dvt/py.typed +1 -0
- dvt/runners/__init__.py +2 -0
- dvt/runners/exposure_runner.py +7 -0
- dvt/runners/no_op_runner.py +46 -0
- dvt/runners/saved_query_runner.py +7 -0
- dvt/selected_resources.py +8 -0
- dvt/task/__init__.py +0 -0
- dvt/task/base.py +504 -0
- dvt/task/build.py +197 -0
- dvt/task/clean.py +57 -0
- dvt/task/clone.py +162 -0
- dvt/task/compile.py +151 -0
- dvt/task/compute.py +366 -0
- dvt/task/debug.py +650 -0
- dvt/task/deps.py +280 -0
- dvt/task/docs/__init__.py +3 -0
- dvt/task/docs/generate.py +408 -0
- dvt/task/docs/index.html +250 -0
- dvt/task/docs/serve.py +28 -0
- dvt/task/freshness.py +323 -0
- dvt/task/function.py +122 -0
- dvt/task/group_lookup.py +46 -0
- dvt/task/init.py +374 -0
- dvt/task/list.py +237 -0
- dvt/task/printer.py +176 -0
- dvt/task/profiles.py +256 -0
- dvt/task/retry.py +175 -0
- dvt/task/run.py +1146 -0
- dvt/task/run_operation.py +142 -0
- dvt/task/runnable.py +802 -0
- dvt/task/seed.py +104 -0
- dvt/task/show.py +150 -0
- dvt/task/snapshot.py +57 -0
- dvt/task/sql.py +111 -0
- dvt/task/test.py +464 -0
- dvt/tests/fixtures/__init__.py +1 -0
- dvt/tests/fixtures/project.py +620 -0
- dvt/tests/util.py +651 -0
- dvt/tracking.py +529 -0
- dvt/utils/__init__.py +3 -0
- dvt/utils/artifact_upload.py +151 -0
- dvt/utils/utils.py +408 -0
- dvt/version.py +249 -0
- dvt_core-1.11.0b4.dist-info/METADATA +252 -0
- dvt_core-1.11.0b4.dist-info/RECORD +261 -0
- dvt_core-1.11.0b4.dist-info/WHEEL +5 -0
- dvt_core-1.11.0b4.dist-info/entry_points.txt +2 -0
- dvt_core-1.11.0b4.dist-info/top_level.txt +1 -0
dvt/task/seed.py
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import random
|
|
2
|
+
from typing import Optional, Type
|
|
3
|
+
|
|
4
|
+
from dvt.artifacts.schemas.results import NodeStatus, RunStatus
|
|
5
|
+
from dvt.contracts.graph.manifest import Manifest
|
|
6
|
+
from dvt.events.types import LogSeedResult, LogStartLine, SeedHeader
|
|
7
|
+
from dvt.graph import ResourceTypeSelector
|
|
8
|
+
from dvt.node_types import NodeType
|
|
9
|
+
from dvt.task import group_lookup
|
|
10
|
+
from dvt.task.base import BaseRunner
|
|
11
|
+
from dvt.task.printer import print_run_end_messages
|
|
12
|
+
from dvt.task.run import ModelRunner, RunTask
|
|
13
|
+
|
|
14
|
+
from dbt_common.events.base_types import EventLevel
|
|
15
|
+
from dbt_common.events.functions import fire_event
|
|
16
|
+
from dbt_common.events.types import Formatting
|
|
17
|
+
from dbt_common.exceptions import DbtInternalError
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class SeedRunner(ModelRunner):
|
|
21
|
+
def describe_node(self) -> str:
|
|
22
|
+
return "seed file {}".format(self.get_node_representation())
|
|
23
|
+
|
|
24
|
+
def before_execute(self) -> None:
|
|
25
|
+
fire_event(
|
|
26
|
+
LogStartLine(
|
|
27
|
+
description=self.describe_node(),
|
|
28
|
+
index=self.node_index,
|
|
29
|
+
total=self.num_nodes,
|
|
30
|
+
node_info=self.node.node_info,
|
|
31
|
+
)
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
def _build_run_model_result(self, model, context):
|
|
35
|
+
result = super()._build_run_model_result(model, context)
|
|
36
|
+
agate_result = context["load_result"]("agate_table")
|
|
37
|
+
result.agate_table = agate_result.table
|
|
38
|
+
return result
|
|
39
|
+
|
|
40
|
+
def compile(self, manifest: Manifest):
|
|
41
|
+
return self.node
|
|
42
|
+
|
|
43
|
+
def print_result_line(self, result):
|
|
44
|
+
model = result.node
|
|
45
|
+
group = group_lookup.get(model.unique_id)
|
|
46
|
+
level = EventLevel.ERROR if result.status == NodeStatus.Error else EventLevel.INFO
|
|
47
|
+
fire_event(
|
|
48
|
+
LogSeedResult(
|
|
49
|
+
status=result.status,
|
|
50
|
+
result_message=result.message,
|
|
51
|
+
index=self.node_index,
|
|
52
|
+
total=self.num_nodes,
|
|
53
|
+
execution_time=result.execution_time,
|
|
54
|
+
schema=self.node.schema,
|
|
55
|
+
relation=model.alias,
|
|
56
|
+
node_info=model.node_info,
|
|
57
|
+
group=group,
|
|
58
|
+
),
|
|
59
|
+
level=level,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class SeedTask(RunTask):
|
|
64
|
+
def raise_on_first_error(self) -> bool:
|
|
65
|
+
return False
|
|
66
|
+
|
|
67
|
+
def get_node_selector(self):
|
|
68
|
+
if self.manifest is None or self.graph is None:
|
|
69
|
+
raise DbtInternalError("manifest and graph must be set to get perform node selection")
|
|
70
|
+
return ResourceTypeSelector(
|
|
71
|
+
graph=self.graph,
|
|
72
|
+
manifest=self.manifest,
|
|
73
|
+
previous_state=self.previous_state,
|
|
74
|
+
resource_types=[NodeType.Seed],
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
def get_runner_type(self, _) -> Optional[Type[BaseRunner]]:
|
|
78
|
+
return SeedRunner
|
|
79
|
+
|
|
80
|
+
def task_end_messages(self, results) -> None:
|
|
81
|
+
if self.args.show:
|
|
82
|
+
self.show_tables(results)
|
|
83
|
+
|
|
84
|
+
print_run_end_messages(results)
|
|
85
|
+
|
|
86
|
+
def show_table(self, result):
|
|
87
|
+
table = result.agate_table
|
|
88
|
+
rand_table = table.order_by(lambda x: random.random())
|
|
89
|
+
|
|
90
|
+
schema = result.node.schema
|
|
91
|
+
alias = result.node.alias
|
|
92
|
+
|
|
93
|
+
header = "Random sample of table: {}.{}".format(schema, alias)
|
|
94
|
+
fire_event(Formatting(""))
|
|
95
|
+
fire_event(SeedHeader(header=header))
|
|
96
|
+
fire_event(Formatting("-" * len(header)))
|
|
97
|
+
|
|
98
|
+
rand_table.print_table(max_rows=10, max_columns=None)
|
|
99
|
+
fire_event(Formatting(""))
|
|
100
|
+
|
|
101
|
+
def show_tables(self, results):
|
|
102
|
+
for result in results:
|
|
103
|
+
if result.status != RunStatus.Error:
|
|
104
|
+
self.show_table(result)
|
dvt/task/show.py
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import io
|
|
2
|
+
import threading
|
|
3
|
+
import time
|
|
4
|
+
|
|
5
|
+
from dvt.artifacts.schemas.run import RunResult, RunStatus
|
|
6
|
+
from dvt.context.providers import generate_runtime_model_context
|
|
7
|
+
from dvt.contracts.graph.nodes import SeedNode
|
|
8
|
+
from dvt.events.types import ShowNode
|
|
9
|
+
from dvt.flags import get_flags
|
|
10
|
+
from dvt.task.base import ConfiguredTask
|
|
11
|
+
from dvt.task.compile import CompileRunner, CompileTask
|
|
12
|
+
from dvt.task.seed import SeedRunner
|
|
13
|
+
|
|
14
|
+
from dbt.adapters.factory import get_adapter
|
|
15
|
+
from dbt_common.events.base_types import EventLevel
|
|
16
|
+
from dbt_common.events.functions import fire_event
|
|
17
|
+
from dbt_common.events.types import Note
|
|
18
|
+
from dbt_common.exceptions import DbtRuntimeError
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ShowRunner(CompileRunner):
|
|
22
|
+
def __init__(self, config, adapter, node, node_index, num_nodes) -> None:
|
|
23
|
+
super().__init__(config, adapter, node, node_index, num_nodes)
|
|
24
|
+
self.run_ephemeral_models = True
|
|
25
|
+
|
|
26
|
+
def execute(self, compiled_node, manifest):
|
|
27
|
+
start_time = time.time()
|
|
28
|
+
|
|
29
|
+
# Allow passing in -1 (or any negative number) to get all rows
|
|
30
|
+
limit = None if self.config.args.limit < 0 else self.config.args.limit
|
|
31
|
+
|
|
32
|
+
model_context = generate_runtime_model_context(compiled_node, self.config, manifest)
|
|
33
|
+
compiled_node.compiled_code = self.adapter.execute_macro(
|
|
34
|
+
macro_name="get_show_sql",
|
|
35
|
+
macro_resolver=manifest,
|
|
36
|
+
context_override=model_context,
|
|
37
|
+
kwargs={
|
|
38
|
+
"compiled_code": model_context["compiled_code"],
|
|
39
|
+
"sql_header": model_context["config"].get("sql_header"),
|
|
40
|
+
"limit": limit,
|
|
41
|
+
},
|
|
42
|
+
)
|
|
43
|
+
adapter_response, execute_result = self.adapter.execute(
|
|
44
|
+
compiled_node.compiled_code, fetch=True
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
end_time = time.time()
|
|
48
|
+
|
|
49
|
+
return RunResult(
|
|
50
|
+
node=compiled_node,
|
|
51
|
+
status=RunStatus.Success,
|
|
52
|
+
timing=[],
|
|
53
|
+
thread_id=threading.current_thread().name,
|
|
54
|
+
execution_time=end_time - start_time,
|
|
55
|
+
message=None,
|
|
56
|
+
adapter_response=adapter_response.to_dict(),
|
|
57
|
+
agate_table=execute_result,
|
|
58
|
+
failures=None,
|
|
59
|
+
batch_results=None,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class ShowTask(CompileTask):
|
|
64
|
+
def _runtime_initialize(self):
|
|
65
|
+
if not (self.args.select or getattr(self.args, "inline", None)):
|
|
66
|
+
raise DbtRuntimeError("Either --select or --inline must be passed to show")
|
|
67
|
+
super()._runtime_initialize()
|
|
68
|
+
|
|
69
|
+
def get_runner_type(self, node):
|
|
70
|
+
if isinstance(node, SeedNode):
|
|
71
|
+
return SeedRunner
|
|
72
|
+
else:
|
|
73
|
+
return ShowRunner
|
|
74
|
+
|
|
75
|
+
def task_end_messages(self, results) -> None:
|
|
76
|
+
is_inline = bool(getattr(self.args, "inline", None))
|
|
77
|
+
|
|
78
|
+
if is_inline:
|
|
79
|
+
matched_results = [result for result in results if result.node.name == "inline_query"]
|
|
80
|
+
else:
|
|
81
|
+
matched_results = []
|
|
82
|
+
for result in results:
|
|
83
|
+
if result.node.name in self.selection_arg[0]:
|
|
84
|
+
matched_results.append(result)
|
|
85
|
+
else:
|
|
86
|
+
fire_event(
|
|
87
|
+
Note(msg=f"Excluded node '{result.node.name}' from results"),
|
|
88
|
+
EventLevel.DEBUG,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
for result in matched_results:
|
|
92
|
+
table = result.agate_table
|
|
93
|
+
|
|
94
|
+
# Hack to get Agate table output as string
|
|
95
|
+
output = io.StringIO()
|
|
96
|
+
if self.args.output == "json":
|
|
97
|
+
table.to_json(path=output)
|
|
98
|
+
else:
|
|
99
|
+
table.print_table(output=output, max_rows=None)
|
|
100
|
+
|
|
101
|
+
node_name = result.node.name
|
|
102
|
+
|
|
103
|
+
if hasattr(result.node, "version") and result.node.version:
|
|
104
|
+
node_name += f".v{result.node.version}"
|
|
105
|
+
|
|
106
|
+
fire_event(
|
|
107
|
+
ShowNode(
|
|
108
|
+
node_name=node_name,
|
|
109
|
+
preview=output.getvalue(),
|
|
110
|
+
is_inline=is_inline,
|
|
111
|
+
output_format=self.args.output,
|
|
112
|
+
unique_id=result.node.unique_id,
|
|
113
|
+
quiet=get_flags().QUIET,
|
|
114
|
+
)
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
def _handle_result(self, result) -> None:
|
|
118
|
+
super()._handle_result(result)
|
|
119
|
+
|
|
120
|
+
if (
|
|
121
|
+
result.node.is_ephemeral_model
|
|
122
|
+
and type(self) is ShowTask
|
|
123
|
+
and (self.args.select or getattr(self.args, "inline", None))
|
|
124
|
+
):
|
|
125
|
+
self.node_results.append(result)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class ShowTaskDirect(ConfiguredTask):
|
|
129
|
+
def run(self):
|
|
130
|
+
adapter = get_adapter(self.config)
|
|
131
|
+
with adapter.connection_named("show", should_release_connection=False):
|
|
132
|
+
limit = None if self.args.limit < 0 else self.args.limit
|
|
133
|
+
response, table = adapter.execute(self.args.inline_direct, fetch=True, limit=limit)
|
|
134
|
+
|
|
135
|
+
output = io.StringIO()
|
|
136
|
+
if self.args.output == "json":
|
|
137
|
+
table.to_json(path=output)
|
|
138
|
+
else:
|
|
139
|
+
table.print_table(output=output, max_rows=None)
|
|
140
|
+
|
|
141
|
+
fire_event(
|
|
142
|
+
ShowNode(
|
|
143
|
+
node_name="direct-query",
|
|
144
|
+
preview=output.getvalue(),
|
|
145
|
+
is_inline=True,
|
|
146
|
+
output_format=self.args.output,
|
|
147
|
+
unique_id="direct-query",
|
|
148
|
+
quiet=get_flags().QUIET,
|
|
149
|
+
)
|
|
150
|
+
)
|
dvt/task/snapshot.py
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
from typing import Optional, Type
|
|
2
|
+
|
|
3
|
+
from dvt.artifacts.schemas.results import NodeStatus
|
|
4
|
+
from dvt.events.types import LogSnapshotResult
|
|
5
|
+
from dvt.graph import ResourceTypeSelector
|
|
6
|
+
from dvt.node_types import NodeType
|
|
7
|
+
from dvt.task import group_lookup
|
|
8
|
+
from dvt.task.base import BaseRunner
|
|
9
|
+
from dvt.task.run import ModelRunner, RunTask
|
|
10
|
+
|
|
11
|
+
from dbt_common.events.base_types import EventLevel
|
|
12
|
+
from dbt_common.events.functions import fire_event
|
|
13
|
+
from dbt_common.exceptions import DbtInternalError
|
|
14
|
+
from dbt_common.utils import cast_dict_to_dict_of_strings
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class SnapshotRunner(ModelRunner):
|
|
18
|
+
def describe_node(self) -> str:
|
|
19
|
+
return "snapshot {}".format(self.get_node_representation())
|
|
20
|
+
|
|
21
|
+
def print_result_line(self, result):
|
|
22
|
+
model = result.node
|
|
23
|
+
group = group_lookup.get(model.unique_id)
|
|
24
|
+
cfg = model.config.to_dict(omit_none=True)
|
|
25
|
+
level = EventLevel.ERROR if result.status == NodeStatus.Error else EventLevel.INFO
|
|
26
|
+
fire_event(
|
|
27
|
+
LogSnapshotResult(
|
|
28
|
+
status=result.status,
|
|
29
|
+
description=self.get_node_representation(),
|
|
30
|
+
cfg=cast_dict_to_dict_of_strings(cfg),
|
|
31
|
+
index=self.node_index,
|
|
32
|
+
total=self.num_nodes,
|
|
33
|
+
execution_time=result.execution_time,
|
|
34
|
+
node_info=model.node_info,
|
|
35
|
+
result_message=result.message,
|
|
36
|
+
group=group,
|
|
37
|
+
),
|
|
38
|
+
level=level,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class SnapshotTask(RunTask):
|
|
43
|
+
def raise_on_first_error(self) -> bool:
|
|
44
|
+
return False
|
|
45
|
+
|
|
46
|
+
def get_node_selector(self):
|
|
47
|
+
if self.manifest is None or self.graph is None:
|
|
48
|
+
raise DbtInternalError("manifest and graph must be set to get perform node selection")
|
|
49
|
+
return ResourceTypeSelector(
|
|
50
|
+
graph=self.graph,
|
|
51
|
+
manifest=self.manifest,
|
|
52
|
+
previous_state=self.previous_state,
|
|
53
|
+
resource_types=[NodeType.Snapshot],
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
def get_runner_type(self, _) -> Optional[Type[BaseRunner]]:
|
|
57
|
+
return SnapshotRunner
|
dvt/task/sql.py
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import traceback
|
|
2
|
+
from abc import abstractmethod
|
|
3
|
+
from datetime import datetime, timezone
|
|
4
|
+
from typing import Generic, TypeVar
|
|
5
|
+
|
|
6
|
+
import dvt.exceptions
|
|
7
|
+
from dvt.contracts.graph.manifest import Manifest
|
|
8
|
+
from dvt.contracts.sql import (
|
|
9
|
+
RemoteCompileResult,
|
|
10
|
+
RemoteCompileResultMixin,
|
|
11
|
+
RemoteRunResult,
|
|
12
|
+
ResultTable,
|
|
13
|
+
)
|
|
14
|
+
from dvt.events.types import SQLRunnerException
|
|
15
|
+
from dvt.task.compile import CompileRunner
|
|
16
|
+
|
|
17
|
+
import dbt_common.exceptions.base
|
|
18
|
+
from dbt_common.events.functions import fire_event
|
|
19
|
+
|
|
20
|
+
SQLResult = TypeVar("SQLResult", bound=RemoteCompileResultMixin)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class GenericSqlRunner(CompileRunner, Generic[SQLResult]):
|
|
24
|
+
def __init__(self, config, adapter, node, node_index, num_nodes) -> None:
|
|
25
|
+
CompileRunner.__init__(self, config, adapter, node, node_index, num_nodes)
|
|
26
|
+
|
|
27
|
+
def handle_exception(self, e, ctx):
|
|
28
|
+
fire_event(
|
|
29
|
+
SQLRunnerException(
|
|
30
|
+
exc=str(e), exc_info=traceback.format_exc(), node_info=self.node.node_info
|
|
31
|
+
)
|
|
32
|
+
)
|
|
33
|
+
# REVIEW: This code is invalid and will always throw.
|
|
34
|
+
if isinstance(e, dbt.exceptions.Exception):
|
|
35
|
+
if isinstance(e, dbt_common.exceptions.DbtRuntimeError):
|
|
36
|
+
e.add_node(ctx.node)
|
|
37
|
+
return e
|
|
38
|
+
|
|
39
|
+
def before_execute(self) -> None:
|
|
40
|
+
pass
|
|
41
|
+
|
|
42
|
+
def after_execute(self, result) -> None:
|
|
43
|
+
pass
|
|
44
|
+
|
|
45
|
+
def compile(self, manifest: Manifest):
|
|
46
|
+
return self.compiler.compile_node(self.node, manifest, {}, write=False)
|
|
47
|
+
|
|
48
|
+
@abstractmethod
|
|
49
|
+
def execute(self, compiled_node, manifest) -> SQLResult:
|
|
50
|
+
pass
|
|
51
|
+
|
|
52
|
+
@abstractmethod
|
|
53
|
+
def from_run_result(self, result, start_time, timing_info) -> SQLResult:
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
def error_result(self, node, error, start_time, timing_info):
|
|
57
|
+
raise error
|
|
58
|
+
|
|
59
|
+
def ephemeral_result(self, node, start_time, timing_info):
|
|
60
|
+
raise dbt_common.exceptions.base.NotImplementedError(
|
|
61
|
+
"cannot execute ephemeral nodes remotely!"
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class SqlCompileRunner(GenericSqlRunner[RemoteCompileResult]):
|
|
66
|
+
def execute(self, compiled_node, manifest) -> RemoteCompileResult:
|
|
67
|
+
return RemoteCompileResult(
|
|
68
|
+
raw_code=compiled_node.raw_code,
|
|
69
|
+
compiled_code=compiled_node.compiled_code,
|
|
70
|
+
node=compiled_node,
|
|
71
|
+
timing=[], # this will get added later
|
|
72
|
+
generated_at=datetime.now(timezone.utc).replace(tzinfo=None),
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
def from_run_result(self, result, start_time, timing_info) -> RemoteCompileResult:
|
|
76
|
+
return RemoteCompileResult(
|
|
77
|
+
raw_code=result.raw_code,
|
|
78
|
+
compiled_code=result.compiled_code,
|
|
79
|
+
node=result.node,
|
|
80
|
+
timing=timing_info,
|
|
81
|
+
generated_at=datetime.now(timezone.utc).replace(tzinfo=None),
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class SqlExecuteRunner(GenericSqlRunner[RemoteRunResult]):
|
|
86
|
+
def execute(self, compiled_node, manifest) -> RemoteRunResult:
|
|
87
|
+
_, execute_result = self.adapter.execute(compiled_node.compiled_code, fetch=True)
|
|
88
|
+
|
|
89
|
+
table = ResultTable(
|
|
90
|
+
column_names=list(execute_result.column_names),
|
|
91
|
+
rows=[list(row) for row in execute_result],
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
return RemoteRunResult(
|
|
95
|
+
raw_code=compiled_node.raw_code,
|
|
96
|
+
compiled_code=compiled_node.compiled_code,
|
|
97
|
+
node=compiled_node,
|
|
98
|
+
table=table,
|
|
99
|
+
timing=[],
|
|
100
|
+
generated_at=datetime.now(timezone.utc).replace(tzinfo=None),
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
def from_run_result(self, result, start_time, timing_info) -> RemoteRunResult:
|
|
104
|
+
return RemoteRunResult(
|
|
105
|
+
raw_code=result.raw_code,
|
|
106
|
+
compiled_code=result.compiled_code,
|
|
107
|
+
node=result.node,
|
|
108
|
+
table=result.table,
|
|
109
|
+
timing=timing_info,
|
|
110
|
+
generated_at=datetime.now(timezone.utc).replace(tzinfo=None),
|
|
111
|
+
)
|