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/clean.py
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from shutil import rmtree
|
|
3
|
+
|
|
4
|
+
from dvt import deprecations
|
|
5
|
+
from dvt.cli.flags import Flags
|
|
6
|
+
from dvt.config.project import Project
|
|
7
|
+
from dvt.events.types import CheckCleanPath, ConfirmCleanPath, FinishedCleanPaths
|
|
8
|
+
from dvt.task.base import BaseTask, move_to_nearest_project_dir
|
|
9
|
+
|
|
10
|
+
from dbt_common.events.functions import fire_event
|
|
11
|
+
from dbt_common.exceptions import DbtRuntimeError
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class CleanTask(BaseTask):
|
|
15
|
+
def __init__(self, args: Flags, config: Project):
|
|
16
|
+
super().__init__(args)
|
|
17
|
+
self.config = config
|
|
18
|
+
self.project = config
|
|
19
|
+
|
|
20
|
+
def run(self) -> None:
|
|
21
|
+
"""
|
|
22
|
+
This function takes all the paths in the target file
|
|
23
|
+
and cleans the project paths that are not protected.
|
|
24
|
+
"""
|
|
25
|
+
project_dir = move_to_nearest_project_dir(self.args.project_dir)
|
|
26
|
+
|
|
27
|
+
potential_clean_paths = set(Path(p).resolve() for p in self.project.clean_targets)
|
|
28
|
+
source_paths = set(
|
|
29
|
+
Path(p).resolve() for p in (*self.project.all_source_paths, *self.project.test_paths)
|
|
30
|
+
)
|
|
31
|
+
clean_paths = potential_clean_paths.difference(source_paths)
|
|
32
|
+
|
|
33
|
+
if potential_clean_paths != clean_paths:
|
|
34
|
+
raise DbtRuntimeError(
|
|
35
|
+
f"dbt will not clean the following source paths: {[str(s) for s in source_paths.intersection(potential_clean_paths)]}"
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
paths_outside_project = set(
|
|
39
|
+
path for path in clean_paths if project_dir not in path.absolute().parents
|
|
40
|
+
)
|
|
41
|
+
if paths_outside_project and self.args.clean_project_files_only:
|
|
42
|
+
raise DbtRuntimeError(
|
|
43
|
+
f"dbt will not clean the following directories outside the project: {[str(p) for p in paths_outside_project]}"
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
if (
|
|
47
|
+
"dbt_modules" in self.project.clean_targets
|
|
48
|
+
and self.config.packages_install_path not in self.config.clean_targets
|
|
49
|
+
):
|
|
50
|
+
deprecations.warn("install-packages-path")
|
|
51
|
+
|
|
52
|
+
for path in clean_paths:
|
|
53
|
+
fire_event(CheckCleanPath(path=str(path)))
|
|
54
|
+
rmtree(path, True)
|
|
55
|
+
fire_event(ConfirmCleanPath(path=str(path)))
|
|
56
|
+
|
|
57
|
+
fire_event(FinishedCleanPaths())
|
dvt/task/clone.py
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import threading
|
|
2
|
+
from typing import AbstractSet, Any, Collection, Iterable, List, Optional, Set, Type
|
|
3
|
+
|
|
4
|
+
from dvt.artifacts.resources.types import NodeType
|
|
5
|
+
from dvt.artifacts.schemas.run import RunResult, RunStatus
|
|
6
|
+
from dvt.clients.jinja import MacroGenerator
|
|
7
|
+
from dvt.context.providers import generate_runtime_model_context
|
|
8
|
+
from dvt.contracts.graph.manifest import Manifest
|
|
9
|
+
from dvt.graph import ResourceTypeSelector
|
|
10
|
+
from dvt.node_types import REFABLE_NODE_TYPES
|
|
11
|
+
from dvt.task.base import BaseRunner, resource_types_from_args
|
|
12
|
+
from dvt.task.run import _validate_materialization_relations_dict
|
|
13
|
+
from dvt.task.runnable import GraphRunnableMode, GraphRunnableTask
|
|
14
|
+
|
|
15
|
+
from dbt.adapters.base import BaseAdapter, BaseRelation
|
|
16
|
+
from dbt_common.dataclass_schema import dbtClassMixin
|
|
17
|
+
from dbt_common.exceptions import CompilationError, DbtInternalError
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class CloneRunner(BaseRunner):
|
|
21
|
+
def before_execute(self) -> None:
|
|
22
|
+
pass
|
|
23
|
+
|
|
24
|
+
def after_execute(self, result) -> None:
|
|
25
|
+
pass
|
|
26
|
+
|
|
27
|
+
def _build_run_model_result(self, model, context):
|
|
28
|
+
result = context["load_result"]("main")
|
|
29
|
+
if result:
|
|
30
|
+
status = RunStatus.Success
|
|
31
|
+
message = str(result.response)
|
|
32
|
+
else:
|
|
33
|
+
status = RunStatus.Success
|
|
34
|
+
message = "No-op"
|
|
35
|
+
adapter_response = {}
|
|
36
|
+
if result and isinstance(result.response, dbtClassMixin):
|
|
37
|
+
adapter_response = result.response.to_dict(omit_none=True)
|
|
38
|
+
return RunResult(
|
|
39
|
+
node=model,
|
|
40
|
+
status=status,
|
|
41
|
+
timing=[],
|
|
42
|
+
thread_id=threading.current_thread().name,
|
|
43
|
+
execution_time=0,
|
|
44
|
+
message=message,
|
|
45
|
+
adapter_response=adapter_response,
|
|
46
|
+
failures=None,
|
|
47
|
+
batch_results=None,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
def compile(self, manifest: Manifest):
|
|
51
|
+
# no-op
|
|
52
|
+
return self.node
|
|
53
|
+
|
|
54
|
+
def _materialization_relations(self, result: Any, model) -> List[BaseRelation]:
|
|
55
|
+
if isinstance(result, str):
|
|
56
|
+
msg = (
|
|
57
|
+
'The materialization ("{}") did not explicitly return a '
|
|
58
|
+
"list of relations to add to the cache.".format(str(model.get_materialization()))
|
|
59
|
+
)
|
|
60
|
+
raise CompilationError(msg, node=model)
|
|
61
|
+
|
|
62
|
+
if isinstance(result, dict):
|
|
63
|
+
return _validate_materialization_relations_dict(result, model)
|
|
64
|
+
|
|
65
|
+
msg = (
|
|
66
|
+
"Invalid return value from materialization, expected a dict "
|
|
67
|
+
'with key "relations", got: {}'.format(str(result))
|
|
68
|
+
)
|
|
69
|
+
raise CompilationError(msg, node=model)
|
|
70
|
+
|
|
71
|
+
def execute(self, model, manifest):
|
|
72
|
+
context = generate_runtime_model_context(model, self.config, manifest)
|
|
73
|
+
materialization_macro = manifest.find_materialization_macro_by_name(
|
|
74
|
+
self.config.project_name, "clone", self.adapter.type()
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
if "config" not in context:
|
|
78
|
+
raise DbtInternalError(
|
|
79
|
+
"Invalid materialization context generated, missing config: {}".format(context)
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
context_config = context["config"]
|
|
83
|
+
|
|
84
|
+
hook_ctx = self.adapter.pre_model_hook(context_config)
|
|
85
|
+
try:
|
|
86
|
+
result = MacroGenerator(materialization_macro, context)()
|
|
87
|
+
finally:
|
|
88
|
+
self.adapter.post_model_hook(context_config, hook_ctx)
|
|
89
|
+
|
|
90
|
+
for relation in self._materialization_relations(result, model):
|
|
91
|
+
self.adapter.cache_added(relation.incorporate(dbt_created=True))
|
|
92
|
+
|
|
93
|
+
return self._build_run_model_result(model, context)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class CloneTask(GraphRunnableTask):
|
|
97
|
+
def raise_on_first_error(self) -> bool:
|
|
98
|
+
return False
|
|
99
|
+
|
|
100
|
+
def get_run_mode(self) -> GraphRunnableMode:
|
|
101
|
+
return GraphRunnableMode.Independent
|
|
102
|
+
|
|
103
|
+
def _get_deferred_manifest(self) -> Optional[Manifest]:
|
|
104
|
+
# Unlike other commands, 'clone' always requires a state manifest
|
|
105
|
+
# Load previous state, regardless of whether --defer flag has been set
|
|
106
|
+
return self._get_previous_state()
|
|
107
|
+
|
|
108
|
+
def get_model_schemas(self, adapter, selected_uids: Iterable[str]) -> Set[BaseRelation]:
|
|
109
|
+
if self.manifest is None:
|
|
110
|
+
raise DbtInternalError("manifest was None in get_model_schemas")
|
|
111
|
+
result: Set[BaseRelation] = set()
|
|
112
|
+
|
|
113
|
+
for node in self.manifest.nodes.values():
|
|
114
|
+
if node.unique_id not in selected_uids:
|
|
115
|
+
continue
|
|
116
|
+
if node.is_relational and not node.is_ephemeral:
|
|
117
|
+
relation = adapter.Relation.create_from(self.config, node)
|
|
118
|
+
result.add(relation.without_identifier())
|
|
119
|
+
|
|
120
|
+
# cache the 'other' schemas too!
|
|
121
|
+
if node.defer_relation: # type: ignore
|
|
122
|
+
other_relation = adapter.Relation.create_from(
|
|
123
|
+
self.config, node.defer_relation # type: ignore
|
|
124
|
+
)
|
|
125
|
+
result.add(other_relation.without_identifier())
|
|
126
|
+
|
|
127
|
+
return result
|
|
128
|
+
|
|
129
|
+
def before_run(self, adapter: BaseAdapter, selected_uids: AbstractSet[str]) -> RunStatus:
|
|
130
|
+
with adapter.connection_named("master"):
|
|
131
|
+
self.defer_to_manifest()
|
|
132
|
+
# only create target schemas, but also cache defer_relation schemas
|
|
133
|
+
schemas_to_create = super().get_model_schemas(adapter, selected_uids)
|
|
134
|
+
self.create_schemas(adapter, schemas_to_create)
|
|
135
|
+
schemas_to_cache = self.get_model_schemas(adapter, selected_uids)
|
|
136
|
+
self.populate_adapter_cache(adapter, schemas_to_cache)
|
|
137
|
+
return RunStatus.Success
|
|
138
|
+
|
|
139
|
+
@property
|
|
140
|
+
def resource_types(self) -> List[NodeType]:
|
|
141
|
+
resource_types: Collection[NodeType] = resource_types_from_args(
|
|
142
|
+
self.args, set(REFABLE_NODE_TYPES), set(REFABLE_NODE_TYPES)
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
# filter out any non-refable node types
|
|
146
|
+
resource_types = [rt for rt in resource_types if rt in REFABLE_NODE_TYPES]
|
|
147
|
+
return list(resource_types)
|
|
148
|
+
|
|
149
|
+
def get_node_selector(self) -> ResourceTypeSelector:
|
|
150
|
+
resource_types = self.resource_types
|
|
151
|
+
|
|
152
|
+
if self.manifest is None or self.graph is None:
|
|
153
|
+
raise DbtInternalError("manifest and graph must be set to get perform node selection")
|
|
154
|
+
return ResourceTypeSelector(
|
|
155
|
+
graph=self.graph,
|
|
156
|
+
manifest=self.manifest,
|
|
157
|
+
previous_state=self.previous_state,
|
|
158
|
+
resource_types=resource_types,
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
def get_runner_type(self, _) -> Optional[Type[BaseRunner]]:
|
|
162
|
+
return CloneRunner
|
dvt/task/compile.py
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import threading
|
|
2
|
+
from typing import Optional, Type
|
|
3
|
+
|
|
4
|
+
from dvt.artifacts.schemas.run import RunResult, RunStatus
|
|
5
|
+
from dvt.contracts.graph.manifest import Manifest
|
|
6
|
+
from dvt.events.types import CompiledNode, ParseInlineNodeError
|
|
7
|
+
from dvt.flags import get_flags
|
|
8
|
+
from dvt.graph import ResourceTypeSelector
|
|
9
|
+
from dvt.node_types import EXECUTABLE_NODE_TYPES, NodeType
|
|
10
|
+
from dvt.parser.manifest import process_node
|
|
11
|
+
from dvt.parser.sql import SqlBlockParser
|
|
12
|
+
from dvt.task.base import BaseRunner
|
|
13
|
+
from dvt.task.runnable import GraphRunnableTask
|
|
14
|
+
|
|
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 CompilationError
|
|
19
|
+
from dbt_common.exceptions import DbtBaseException as DbtException
|
|
20
|
+
from dbt_common.exceptions import DbtInternalError
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class CompileRunner(BaseRunner):
|
|
24
|
+
def before_execute(self) -> None:
|
|
25
|
+
pass
|
|
26
|
+
|
|
27
|
+
def after_execute(self, result) -> None:
|
|
28
|
+
pass
|
|
29
|
+
|
|
30
|
+
def execute(self, compiled_node, manifest):
|
|
31
|
+
return RunResult(
|
|
32
|
+
node=compiled_node,
|
|
33
|
+
status=RunStatus.Success,
|
|
34
|
+
timing=[],
|
|
35
|
+
thread_id=threading.current_thread().name,
|
|
36
|
+
execution_time=0,
|
|
37
|
+
message=None,
|
|
38
|
+
adapter_response={},
|
|
39
|
+
failures=None,
|
|
40
|
+
batch_results=None,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
def compile(self, manifest: Manifest):
|
|
44
|
+
return self.compiler.compile_node(self.node, manifest, {})
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class CompileTask(GraphRunnableTask):
|
|
48
|
+
# We add a new inline node to the manifest during initialization
|
|
49
|
+
# it should be removed before the task is complete
|
|
50
|
+
_inline_node_id = None
|
|
51
|
+
|
|
52
|
+
def raise_on_first_error(self) -> bool:
|
|
53
|
+
return True
|
|
54
|
+
|
|
55
|
+
def get_node_selector(self) -> ResourceTypeSelector:
|
|
56
|
+
if getattr(self.args, "inline", None):
|
|
57
|
+
resource_types = [NodeType.SqlOperation]
|
|
58
|
+
else:
|
|
59
|
+
resource_types = EXECUTABLE_NODE_TYPES
|
|
60
|
+
|
|
61
|
+
if self.manifest is None or self.graph is None:
|
|
62
|
+
raise DbtInternalError("manifest and graph must be set to get perform node selection")
|
|
63
|
+
return ResourceTypeSelector(
|
|
64
|
+
graph=self.graph,
|
|
65
|
+
manifest=self.manifest,
|
|
66
|
+
previous_state=self.previous_state,
|
|
67
|
+
resource_types=resource_types,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
def get_runner_type(self, _) -> Optional[Type[BaseRunner]]:
|
|
71
|
+
return CompileRunner
|
|
72
|
+
|
|
73
|
+
def task_end_messages(self, results) -> None:
|
|
74
|
+
is_inline = bool(getattr(self.args, "inline", None))
|
|
75
|
+
output_format = getattr(self.args, "output", "text")
|
|
76
|
+
|
|
77
|
+
if is_inline:
|
|
78
|
+
matched_results = [result for result in results if result.node.name == "inline_query"]
|
|
79
|
+
elif self.selection_arg:
|
|
80
|
+
matched_results = []
|
|
81
|
+
for result in results:
|
|
82
|
+
if result.node.name in self.selection_arg[0]:
|
|
83
|
+
matched_results.append(result)
|
|
84
|
+
else:
|
|
85
|
+
fire_event(
|
|
86
|
+
Note(msg=f"Excluded node '{result.node.name}' from results"),
|
|
87
|
+
EventLevel.DEBUG,
|
|
88
|
+
)
|
|
89
|
+
# No selector passed, compiling all nodes
|
|
90
|
+
else:
|
|
91
|
+
matched_results = []
|
|
92
|
+
|
|
93
|
+
for result in matched_results:
|
|
94
|
+
fire_event(
|
|
95
|
+
CompiledNode(
|
|
96
|
+
node_name=result.node.name,
|
|
97
|
+
compiled=result.node.compiled_code,
|
|
98
|
+
is_inline=is_inline,
|
|
99
|
+
output_format=output_format,
|
|
100
|
+
unique_id=result.node.unique_id,
|
|
101
|
+
quiet=get_flags().QUIET,
|
|
102
|
+
)
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
def _runtime_initialize(self):
|
|
106
|
+
if getattr(self.args, "inline", None):
|
|
107
|
+
try:
|
|
108
|
+
block_parser = SqlBlockParser(
|
|
109
|
+
project=self.config, manifest=self.manifest, root_project=self.config
|
|
110
|
+
)
|
|
111
|
+
sql_node = block_parser.parse_remote(self.args.inline, "inline_query")
|
|
112
|
+
process_node(self.config, self.manifest, sql_node)
|
|
113
|
+
# Special hack to remove disabled, if it's there. This would only happen
|
|
114
|
+
# if all models are disabled in dbt_project
|
|
115
|
+
if sql_node.config.enabled is False:
|
|
116
|
+
sql_node.config.enabled = True
|
|
117
|
+
self.manifest.disabled.pop(sql_node.unique_id)
|
|
118
|
+
self.manifest.nodes[sql_node.unique_id] = sql_node
|
|
119
|
+
# keep track of the node added to the manifest
|
|
120
|
+
self._inline_node_id = sql_node.unique_id
|
|
121
|
+
except CompilationError as exc:
|
|
122
|
+
fire_event(
|
|
123
|
+
ParseInlineNodeError(
|
|
124
|
+
exc=str(exc.msg),
|
|
125
|
+
node_info={
|
|
126
|
+
"node_path": "sql/inline_query",
|
|
127
|
+
"node_name": "inline_query",
|
|
128
|
+
"unique_id": "sqloperation.test.inline_query",
|
|
129
|
+
"node_status": "failed",
|
|
130
|
+
},
|
|
131
|
+
)
|
|
132
|
+
)
|
|
133
|
+
raise DbtException("Error parsing inline query")
|
|
134
|
+
super()._runtime_initialize()
|
|
135
|
+
|
|
136
|
+
def after_run(self, adapter, results) -> None:
|
|
137
|
+
# remove inline node from manifest
|
|
138
|
+
if self._inline_node_id:
|
|
139
|
+
self.manifest.nodes.pop(self._inline_node_id)
|
|
140
|
+
self._inline_node_id = None
|
|
141
|
+
super().after_run(adapter, results)
|
|
142
|
+
|
|
143
|
+
def _handle_result(self, result) -> None:
|
|
144
|
+
super()._handle_result(result)
|
|
145
|
+
|
|
146
|
+
if (
|
|
147
|
+
result.node.is_ephemeral_model
|
|
148
|
+
and type(self) is CompileTask
|
|
149
|
+
and (self.args.select or getattr(self.args, "inline", None))
|
|
150
|
+
):
|
|
151
|
+
self.node_results.append(result)
|