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.

Files changed (261) hide show
  1. dvt/__init__.py +7 -0
  2. dvt/_pydantic_shim.py +26 -0
  3. dvt/adapters/__init__.py +16 -0
  4. dvt/adapters/multi_adapter_manager.py +268 -0
  5. dvt/artifacts/__init__.py +0 -0
  6. dvt/artifacts/exceptions/__init__.py +1 -0
  7. dvt/artifacts/exceptions/schemas.py +31 -0
  8. dvt/artifacts/resources/__init__.py +116 -0
  9. dvt/artifacts/resources/base.py +68 -0
  10. dvt/artifacts/resources/types.py +93 -0
  11. dvt/artifacts/resources/v1/analysis.py +10 -0
  12. dvt/artifacts/resources/v1/catalog.py +23 -0
  13. dvt/artifacts/resources/v1/components.py +275 -0
  14. dvt/artifacts/resources/v1/config.py +282 -0
  15. dvt/artifacts/resources/v1/documentation.py +11 -0
  16. dvt/artifacts/resources/v1/exposure.py +52 -0
  17. dvt/artifacts/resources/v1/function.py +53 -0
  18. dvt/artifacts/resources/v1/generic_test.py +32 -0
  19. dvt/artifacts/resources/v1/group.py +22 -0
  20. dvt/artifacts/resources/v1/hook.py +11 -0
  21. dvt/artifacts/resources/v1/macro.py +30 -0
  22. dvt/artifacts/resources/v1/metric.py +173 -0
  23. dvt/artifacts/resources/v1/model.py +146 -0
  24. dvt/artifacts/resources/v1/owner.py +10 -0
  25. dvt/artifacts/resources/v1/saved_query.py +112 -0
  26. dvt/artifacts/resources/v1/seed.py +42 -0
  27. dvt/artifacts/resources/v1/semantic_layer_components.py +72 -0
  28. dvt/artifacts/resources/v1/semantic_model.py +315 -0
  29. dvt/artifacts/resources/v1/singular_test.py +14 -0
  30. dvt/artifacts/resources/v1/snapshot.py +92 -0
  31. dvt/artifacts/resources/v1/source_definition.py +85 -0
  32. dvt/artifacts/resources/v1/sql_operation.py +10 -0
  33. dvt/artifacts/resources/v1/unit_test_definition.py +78 -0
  34. dvt/artifacts/schemas/__init__.py +0 -0
  35. dvt/artifacts/schemas/base.py +191 -0
  36. dvt/artifacts/schemas/batch_results.py +24 -0
  37. dvt/artifacts/schemas/catalog/__init__.py +12 -0
  38. dvt/artifacts/schemas/catalog/v1/__init__.py +0 -0
  39. dvt/artifacts/schemas/catalog/v1/catalog.py +60 -0
  40. dvt/artifacts/schemas/freshness/__init__.py +1 -0
  41. dvt/artifacts/schemas/freshness/v3/__init__.py +0 -0
  42. dvt/artifacts/schemas/freshness/v3/freshness.py +159 -0
  43. dvt/artifacts/schemas/manifest/__init__.py +2 -0
  44. dvt/artifacts/schemas/manifest/v12/__init__.py +0 -0
  45. dvt/artifacts/schemas/manifest/v12/manifest.py +212 -0
  46. dvt/artifacts/schemas/results.py +148 -0
  47. dvt/artifacts/schemas/run/__init__.py +2 -0
  48. dvt/artifacts/schemas/run/v5/__init__.py +0 -0
  49. dvt/artifacts/schemas/run/v5/run.py +184 -0
  50. dvt/artifacts/schemas/upgrades/__init__.py +4 -0
  51. dvt/artifacts/schemas/upgrades/upgrade_manifest.py +174 -0
  52. dvt/artifacts/schemas/upgrades/upgrade_manifest_dbt_version.py +2 -0
  53. dvt/artifacts/utils/validation.py +153 -0
  54. dvt/cli/__init__.py +1 -0
  55. dvt/cli/context.py +16 -0
  56. dvt/cli/exceptions.py +56 -0
  57. dvt/cli/flags.py +558 -0
  58. dvt/cli/main.py +971 -0
  59. dvt/cli/option_types.py +121 -0
  60. dvt/cli/options.py +79 -0
  61. dvt/cli/params.py +803 -0
  62. dvt/cli/requires.py +478 -0
  63. dvt/cli/resolvers.py +32 -0
  64. dvt/cli/types.py +40 -0
  65. dvt/clients/__init__.py +0 -0
  66. dvt/clients/checked_load.py +82 -0
  67. dvt/clients/git.py +164 -0
  68. dvt/clients/jinja.py +206 -0
  69. dvt/clients/jinja_static.py +245 -0
  70. dvt/clients/registry.py +192 -0
  71. dvt/clients/yaml_helper.py +68 -0
  72. dvt/compilation.py +833 -0
  73. dvt/compute/__init__.py +26 -0
  74. dvt/compute/base.py +288 -0
  75. dvt/compute/engines/__init__.py +13 -0
  76. dvt/compute/engines/duckdb_engine.py +368 -0
  77. dvt/compute/engines/spark_engine.py +273 -0
  78. dvt/compute/query_analyzer.py +212 -0
  79. dvt/compute/router.py +483 -0
  80. dvt/config/__init__.py +4 -0
  81. dvt/config/catalogs.py +95 -0
  82. dvt/config/compute_config.py +406 -0
  83. dvt/config/profile.py +411 -0
  84. dvt/config/profiles_v2.py +464 -0
  85. dvt/config/project.py +893 -0
  86. dvt/config/renderer.py +232 -0
  87. dvt/config/runtime.py +491 -0
  88. dvt/config/selectors.py +209 -0
  89. dvt/config/utils.py +78 -0
  90. dvt/connectors/.gitignore +6 -0
  91. dvt/connectors/README.md +306 -0
  92. dvt/connectors/catalog.yml +217 -0
  93. dvt/connectors/download_connectors.py +300 -0
  94. dvt/constants.py +29 -0
  95. dvt/context/__init__.py +0 -0
  96. dvt/context/base.py +746 -0
  97. dvt/context/configured.py +136 -0
  98. dvt/context/context_config.py +350 -0
  99. dvt/context/docs.py +82 -0
  100. dvt/context/exceptions_jinja.py +179 -0
  101. dvt/context/macro_resolver.py +195 -0
  102. dvt/context/macros.py +171 -0
  103. dvt/context/manifest.py +73 -0
  104. dvt/context/providers.py +2198 -0
  105. dvt/context/query_header.py +14 -0
  106. dvt/context/secret.py +59 -0
  107. dvt/context/target.py +74 -0
  108. dvt/contracts/__init__.py +0 -0
  109. dvt/contracts/files.py +413 -0
  110. dvt/contracts/graph/__init__.py +0 -0
  111. dvt/contracts/graph/manifest.py +1904 -0
  112. dvt/contracts/graph/metrics.py +98 -0
  113. dvt/contracts/graph/model_config.py +71 -0
  114. dvt/contracts/graph/node_args.py +42 -0
  115. dvt/contracts/graph/nodes.py +1806 -0
  116. dvt/contracts/graph/semantic_manifest.py +233 -0
  117. dvt/contracts/graph/unparsed.py +812 -0
  118. dvt/contracts/project.py +417 -0
  119. dvt/contracts/results.py +53 -0
  120. dvt/contracts/selection.py +23 -0
  121. dvt/contracts/sql.py +86 -0
  122. dvt/contracts/state.py +69 -0
  123. dvt/contracts/util.py +46 -0
  124. dvt/deprecations.py +347 -0
  125. dvt/deps/__init__.py +0 -0
  126. dvt/deps/base.py +153 -0
  127. dvt/deps/git.py +196 -0
  128. dvt/deps/local.py +80 -0
  129. dvt/deps/registry.py +131 -0
  130. dvt/deps/resolver.py +149 -0
  131. dvt/deps/tarball.py +121 -0
  132. dvt/docs/source/_ext/dbt_click.py +118 -0
  133. dvt/docs/source/conf.py +32 -0
  134. dvt/env_vars.py +64 -0
  135. dvt/event_time/event_time.py +40 -0
  136. dvt/event_time/sample_window.py +60 -0
  137. dvt/events/__init__.py +16 -0
  138. dvt/events/base_types.py +37 -0
  139. dvt/events/core_types_pb2.py +2 -0
  140. dvt/events/logging.py +109 -0
  141. dvt/events/types.py +2534 -0
  142. dvt/exceptions.py +1487 -0
  143. dvt/flags.py +89 -0
  144. dvt/graph/__init__.py +11 -0
  145. dvt/graph/cli.py +248 -0
  146. dvt/graph/graph.py +172 -0
  147. dvt/graph/queue.py +213 -0
  148. dvt/graph/selector.py +375 -0
  149. dvt/graph/selector_methods.py +976 -0
  150. dvt/graph/selector_spec.py +223 -0
  151. dvt/graph/thread_pool.py +18 -0
  152. dvt/hooks.py +21 -0
  153. dvt/include/README.md +49 -0
  154. dvt/include/__init__.py +3 -0
  155. dvt/include/global_project.py +4 -0
  156. dvt/include/starter_project/.gitignore +4 -0
  157. dvt/include/starter_project/README.md +15 -0
  158. dvt/include/starter_project/__init__.py +3 -0
  159. dvt/include/starter_project/analyses/.gitkeep +0 -0
  160. dvt/include/starter_project/dvt_project.yml +36 -0
  161. dvt/include/starter_project/macros/.gitkeep +0 -0
  162. dvt/include/starter_project/models/example/my_first_dbt_model.sql +27 -0
  163. dvt/include/starter_project/models/example/my_second_dbt_model.sql +6 -0
  164. dvt/include/starter_project/models/example/schema.yml +21 -0
  165. dvt/include/starter_project/seeds/.gitkeep +0 -0
  166. dvt/include/starter_project/snapshots/.gitkeep +0 -0
  167. dvt/include/starter_project/tests/.gitkeep +0 -0
  168. dvt/internal_deprecations.py +27 -0
  169. dvt/jsonschemas/__init__.py +3 -0
  170. dvt/jsonschemas/jsonschemas.py +309 -0
  171. dvt/jsonschemas/project/0.0.110.json +4717 -0
  172. dvt/jsonschemas/project/0.0.85.json +2015 -0
  173. dvt/jsonschemas/resources/0.0.110.json +2636 -0
  174. dvt/jsonschemas/resources/0.0.85.json +2536 -0
  175. dvt/jsonschemas/resources/latest.json +6773 -0
  176. dvt/links.py +4 -0
  177. dvt/materializations/__init__.py +0 -0
  178. dvt/materializations/incremental/__init__.py +0 -0
  179. dvt/materializations/incremental/microbatch.py +235 -0
  180. dvt/mp_context.py +8 -0
  181. dvt/node_types.py +37 -0
  182. dvt/parser/__init__.py +23 -0
  183. dvt/parser/analysis.py +21 -0
  184. dvt/parser/base.py +549 -0
  185. dvt/parser/common.py +267 -0
  186. dvt/parser/docs.py +52 -0
  187. dvt/parser/fixtures.py +51 -0
  188. dvt/parser/functions.py +30 -0
  189. dvt/parser/generic_test.py +100 -0
  190. dvt/parser/generic_test_builders.py +334 -0
  191. dvt/parser/hooks.py +119 -0
  192. dvt/parser/macros.py +137 -0
  193. dvt/parser/manifest.py +2204 -0
  194. dvt/parser/models.py +574 -0
  195. dvt/parser/partial.py +1179 -0
  196. dvt/parser/read_files.py +445 -0
  197. dvt/parser/schema_generic_tests.py +423 -0
  198. dvt/parser/schema_renderer.py +111 -0
  199. dvt/parser/schema_yaml_readers.py +936 -0
  200. dvt/parser/schemas.py +1467 -0
  201. dvt/parser/search.py +149 -0
  202. dvt/parser/seeds.py +28 -0
  203. dvt/parser/singular_test.py +20 -0
  204. dvt/parser/snapshots.py +44 -0
  205. dvt/parser/sources.py +557 -0
  206. dvt/parser/sql.py +63 -0
  207. dvt/parser/unit_tests.py +622 -0
  208. dvt/plugins/__init__.py +20 -0
  209. dvt/plugins/contracts.py +10 -0
  210. dvt/plugins/exceptions.py +2 -0
  211. dvt/plugins/manager.py +164 -0
  212. dvt/plugins/manifest.py +21 -0
  213. dvt/profiler.py +20 -0
  214. dvt/py.typed +1 -0
  215. dvt/runners/__init__.py +2 -0
  216. dvt/runners/exposure_runner.py +7 -0
  217. dvt/runners/no_op_runner.py +46 -0
  218. dvt/runners/saved_query_runner.py +7 -0
  219. dvt/selected_resources.py +8 -0
  220. dvt/task/__init__.py +0 -0
  221. dvt/task/base.py +504 -0
  222. dvt/task/build.py +197 -0
  223. dvt/task/clean.py +57 -0
  224. dvt/task/clone.py +162 -0
  225. dvt/task/compile.py +151 -0
  226. dvt/task/compute.py +366 -0
  227. dvt/task/debug.py +650 -0
  228. dvt/task/deps.py +280 -0
  229. dvt/task/docs/__init__.py +3 -0
  230. dvt/task/docs/generate.py +408 -0
  231. dvt/task/docs/index.html +250 -0
  232. dvt/task/docs/serve.py +28 -0
  233. dvt/task/freshness.py +323 -0
  234. dvt/task/function.py +122 -0
  235. dvt/task/group_lookup.py +46 -0
  236. dvt/task/init.py +374 -0
  237. dvt/task/list.py +237 -0
  238. dvt/task/printer.py +176 -0
  239. dvt/task/profiles.py +256 -0
  240. dvt/task/retry.py +175 -0
  241. dvt/task/run.py +1146 -0
  242. dvt/task/run_operation.py +142 -0
  243. dvt/task/runnable.py +802 -0
  244. dvt/task/seed.py +104 -0
  245. dvt/task/show.py +150 -0
  246. dvt/task/snapshot.py +57 -0
  247. dvt/task/sql.py +111 -0
  248. dvt/task/test.py +464 -0
  249. dvt/tests/fixtures/__init__.py +1 -0
  250. dvt/tests/fixtures/project.py +620 -0
  251. dvt/tests/util.py +651 -0
  252. dvt/tracking.py +529 -0
  253. dvt/utils/__init__.py +3 -0
  254. dvt/utils/artifact_upload.py +151 -0
  255. dvt/utils/utils.py +408 -0
  256. dvt/version.py +249 -0
  257. dvt_core-1.11.0b4.dist-info/METADATA +252 -0
  258. dvt_core-1.11.0b4.dist-info/RECORD +261 -0
  259. dvt_core-1.11.0b4.dist-info/WHEEL +5 -0
  260. dvt_core-1.11.0b4.dist-info/entry_points.txt +2 -0
  261. 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)