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
@@ -0,0 +1,223 @@
1
+ import os
2
+ import re
3
+ from abc import ABCMeta, abstractmethod
4
+ from dataclasses import dataclass
5
+ from typing import Any, Dict, Iterable, Iterator, List, Optional, Set, Tuple, Union
6
+
7
+ from dvt.exceptions import InvalidSelectorError
8
+ from dvt.flags import get_flags
9
+
10
+ from dbt_common.dataclass_schema import StrEnum, dbtClassMixin
11
+ from dbt_common.exceptions import DbtRuntimeError
12
+
13
+ from .graph import UniqueId
14
+ from .selector_methods import MethodName
15
+
16
+ RAW_SELECTOR_PATTERN = re.compile(
17
+ r"\A"
18
+ r"(?P<childrens_parents>(\@))?"
19
+ r"(?P<parents>((?P<parents_depth>(\d*))\+))?"
20
+ r"((?P<method>([\w.]+)):)?(?P<value>(.*?))"
21
+ r"(?P<children>(\+(?P<children_depth>(\d*))))?"
22
+ r"\Z"
23
+ )
24
+ SELECTOR_METHOD_SEPARATOR = "."
25
+
26
+
27
+ class IndirectSelection(StrEnum):
28
+ Eager = "eager"
29
+ Cautious = "cautious"
30
+ Buildable = "buildable"
31
+ Empty = "empty"
32
+
33
+
34
+ def _probably_path(value: str):
35
+ """Decide if the value is probably a path. Windows has two path separators, so
36
+ we should check both sep ('\\') and altsep ('/') there.
37
+ """
38
+ if os.path.sep in value:
39
+ return True
40
+ elif os.path.altsep is not None and os.path.altsep in value:
41
+ return True
42
+ else:
43
+ return False
44
+
45
+
46
+ def _match_to_int(match: Dict[str, str], key: str) -> Optional[int]:
47
+ raw = match.get(key)
48
+ # turn the empty string into None, too.
49
+ if not raw:
50
+ return None
51
+ try:
52
+ return int(raw)
53
+ except ValueError as exc:
54
+ raise DbtRuntimeError(f"Invalid node spec - could not handle parent depth {raw}") from exc
55
+
56
+
57
+ SelectionSpec = Union[
58
+ "SelectionCriteria",
59
+ "SelectionIntersection",
60
+ "SelectionDifference",
61
+ "SelectionUnion",
62
+ ]
63
+
64
+
65
+ @dataclass
66
+ class SelectionCriteria:
67
+ raw: Any
68
+ method: MethodName
69
+ method_arguments: List[str]
70
+ value: Any
71
+ childrens_parents: bool
72
+ parents: bool
73
+ parents_depth: Optional[int]
74
+ children: bool
75
+ children_depth: Optional[int]
76
+ indirect_selection: IndirectSelection = IndirectSelection.Eager
77
+
78
+ def __post_init__(self):
79
+ if self.children and self.childrens_parents:
80
+ raise DbtRuntimeError(
81
+ f'Invalid node spec {self.raw} - "@" prefix and "+" suffix ' "are incompatible"
82
+ )
83
+
84
+ @classmethod
85
+ def default_method(cls, value: str) -> MethodName:
86
+ if _probably_path(value):
87
+ return MethodName.Path
88
+ elif value.lower().endswith((".sql", ".py", ".csv")):
89
+ return MethodName.File
90
+ else:
91
+ return MethodName.FQN
92
+
93
+ @classmethod
94
+ def parse_method(cls, groupdict: Dict[str, Any]) -> Tuple[MethodName, List[str]]:
95
+ raw_method = groupdict.get("method")
96
+ if raw_method is None:
97
+ return cls.default_method(groupdict["value"]), []
98
+
99
+ method_parts: List[str] = raw_method.split(SELECTOR_METHOD_SEPARATOR)
100
+ try:
101
+ method_name = MethodName(method_parts[0])
102
+ except ValueError as exc:
103
+ raise InvalidSelectorError(f"'{method_parts[0]}' is not a valid method name") from exc
104
+
105
+ # Following is for cases like config.severity and config.materialized
106
+ method_arguments: List[str] = method_parts[1:]
107
+
108
+ return method_name, method_arguments
109
+
110
+ @classmethod
111
+ def selection_criteria_from_dict(
112
+ cls,
113
+ raw: Any,
114
+ dct: Dict[str, Any],
115
+ ) -> "SelectionCriteria":
116
+ if "value" not in dct:
117
+ raise DbtRuntimeError(f'Invalid node spec "{raw}" - no search value!')
118
+ method_name, method_arguments = cls.parse_method(dct)
119
+
120
+ parents_depth = _match_to_int(dct, "parents_depth")
121
+ children_depth = _match_to_int(dct, "children_depth")
122
+
123
+ # If defined field in selector, override CLI flag
124
+ indirect_selection = IndirectSelection(
125
+ dct.get("indirect_selection", get_flags().INDIRECT_SELECTION)
126
+ )
127
+
128
+ return cls(
129
+ raw=raw,
130
+ method=method_name,
131
+ method_arguments=method_arguments,
132
+ value=dct["value"],
133
+ childrens_parents=bool(dct.get("childrens_parents")),
134
+ parents=bool(dct.get("parents")),
135
+ parents_depth=parents_depth,
136
+ children=bool(dct.get("children")),
137
+ children_depth=children_depth,
138
+ indirect_selection=indirect_selection,
139
+ )
140
+
141
+ @classmethod
142
+ def dict_from_single_spec(cls, raw: str):
143
+ result = RAW_SELECTOR_PATTERN.match(raw)
144
+ if result is None:
145
+ return {"error": "Invalid selector spec"}
146
+ dct: Dict[str, Any] = result.groupdict()
147
+ method_name, method_arguments = cls.parse_method(dct)
148
+ meth_name = str(method_name)
149
+ if method_arguments:
150
+ meth_name += "." + ".".join(method_arguments)
151
+ dct["method"] = meth_name
152
+ dct = {k: v for k, v in dct.items() if (v is not None and v != "")}
153
+ if "childrens_parents" in dct:
154
+ dct["childrens_parents"] = bool(dct.get("childrens_parents"))
155
+ if "parents" in dct:
156
+ dct["parents"] = bool(dct.get("parents"))
157
+ if "children" in dct:
158
+ dct["children"] = bool(dct.get("children"))
159
+ return dct
160
+
161
+ @classmethod
162
+ def from_single_spec(cls, raw: str) -> "SelectionCriteria":
163
+ result = RAW_SELECTOR_PATTERN.match(raw)
164
+ if result is None:
165
+ # bad spec!
166
+ raise DbtRuntimeError(f'Invalid selector spec "{raw}"')
167
+
168
+ return cls.selection_criteria_from_dict(raw, result.groupdict())
169
+
170
+
171
+ class BaseSelectionGroup(dbtClassMixin, Iterable[SelectionSpec], metaclass=ABCMeta):
172
+ def __init__(
173
+ self,
174
+ components: Iterable[SelectionSpec],
175
+ indirect_selection: IndirectSelection = IndirectSelection.Eager,
176
+ expect_exists: bool = False,
177
+ raw: Any = None,
178
+ ) -> None:
179
+ self.components: List[SelectionSpec] = list(components)
180
+ self.expect_exists = expect_exists
181
+ self.raw = raw
182
+ self.indirect_selection = indirect_selection
183
+
184
+ def __iter__(self) -> Iterator[SelectionSpec]:
185
+ for component in self.components:
186
+ yield component
187
+
188
+ @abstractmethod
189
+ def combine_selections(
190
+ self,
191
+ selections: List[Set[UniqueId]],
192
+ ) -> Set[UniqueId]:
193
+ raise NotImplementedError("_combine_selections not implemented!")
194
+
195
+ def combined(self, selections: List[Set[UniqueId]]) -> Set[UniqueId]:
196
+ if not selections:
197
+ return set()
198
+
199
+ return self.combine_selections(selections)
200
+
201
+
202
+ class SelectionIntersection(BaseSelectionGroup):
203
+ def combine_selections(
204
+ self,
205
+ selections: List[Set[UniqueId]],
206
+ ) -> Set[UniqueId]:
207
+ return set.intersection(*selections)
208
+
209
+
210
+ class SelectionDifference(BaseSelectionGroup):
211
+ def combine_selections(
212
+ self,
213
+ selections: List[Set[UniqueId]],
214
+ ) -> Set[UniqueId]:
215
+ return set.difference(*selections)
216
+
217
+
218
+ class SelectionUnion(BaseSelectionGroup):
219
+ def combine_selections(
220
+ self,
221
+ selections: List[Set[UniqueId]],
222
+ ) -> Set[UniqueId]:
223
+ return set.union(*selections)
@@ -0,0 +1,18 @@
1
+ from __future__ import annotations
2
+
3
+ from multiprocessing.pool import ThreadPool
4
+
5
+
6
+ class DbtThreadPool(ThreadPool):
7
+ """A ThreadPool that tracks whether or not it's been closed"""
8
+
9
+ def __init__(self, *args, **kwargs):
10
+ super().__init__(*args, **kwargs)
11
+ self.closed = False
12
+
13
+ def close(self):
14
+ self.closed = True
15
+ super().close()
16
+
17
+ def is_closed(self):
18
+ return self.closed
dvt/hooks.py ADDED
@@ -0,0 +1,21 @@
1
+ import json
2
+ from typing import Any, Dict, Union
3
+
4
+ from dbt_common.dataclass_schema import StrEnum
5
+
6
+
7
+ class ModelHookType(StrEnum):
8
+ PreHook = "pre-hook"
9
+ PostHook = "post-hook"
10
+
11
+
12
+ def get_hook_dict(source: Union[str, Dict[str, Any]]) -> Dict[str, Any]:
13
+ """From a source string-or-dict, get a dictionary that can be passed to
14
+ Hook.from_dict
15
+ """
16
+ if isinstance(source, dict):
17
+ return source
18
+ try:
19
+ return json.loads(source)
20
+ except ValueError:
21
+ return {"sql": source}
dvt/include/README.md ADDED
@@ -0,0 +1,49 @@
1
+ # Include Module
2
+
3
+ The Include module is responsible for the starter project scaffold.
4
+
5
+ # Directories
6
+
7
+ ## `starter_project`
8
+ Produces the default project after running the `dbt init` command for the CLI. `dbt-cloud` initializes the project by using [dbt-starter-project](https://github.com/dbt-labs/dbt-starter-project).
9
+
10
+ # adapter.dispatch
11
+ Packages (e.g. `include` directories of adapters, any [hub](https://hub.getdbt.com/)-hosted package) can be interpreted as namespaces of functions a.k.a macros. In `dbt`'s macrospace, we take advantage of the multiple dispatch programming language concept. In short, multiple dispatch supports dynamic searching for a function across several namespaces—usually in a manually specified manner/order.
12
+
13
+ Adapters can have their own implementation of the same macro X. For example, a macro executed by `dbt-redshift` may need a specific implementation different from `dbt-snowflake`'s macro. We use multiple dispatch via `adapter.dispatch`, a Jinja function, which enables polymorphic macro invocations. The chosen implementation is selected according to what the `adapter` object is set to at runtime (it could be for redshift, postgres, and so on).
14
+
15
+ For more on this object, check out the dbt docs [here](https://docs.getdbt.com/reference/dbt-jinja-functions/adapter).
16
+
17
+ # dbt and database adapter python package interop
18
+
19
+ Let’s say we have a fictional python app named `dbt-core` with this structure
20
+
21
+ ```
22
+ dbt
23
+ ├── adapters
24
+ │   └── base.py
25
+ ├── cli.py
26
+ └── main.py
27
+ ```
28
+
29
+ `pip install dbt-core` will install this application in my python environment, maintaining the same structure. Note that `dbt.adapters` only contains a `base.py`. In this example, we can assume that base.py includes an abstract class for creating connections. Let’s say we wanted to create an postgres adapter that this app could use, and can be installed independently. We can create a python package with the following structure called `dbt-postgres`
30
+ ```
31
+ dbt
32
+ └── adapters
33
+ └── postgres
34
+ └── impl.py
35
+ ```
36
+
37
+ `pip install dbt-postgres` will install this package in the python environment, maintaining the same structure again. Let’s say `impl.py` imports `dbt.adapters.base` and implements a concrete class inheriting from the abstract class in `base.py` from the `dbt-core` package. Since our top level package is named the same in both packages, `pip` will put this in the same place. We end up with this installed in our python environment.
38
+
39
+ ```
40
+ dbt
41
+ ├── adapters
42
+ │   ├── base.py
43
+ │   └── postgres
44
+ │   └── impl.py
45
+ ├── cli.py
46
+ └── main.py
47
+ ```
48
+
49
+ `dbt.adapters` now has a postgres module that dbt can easily find and call directly. dbt and its adapters follows the same type of file structure convention. This is the magic that allows you to import `dbt.*` in database adapters, and using a factory pattern in dbt-core, we can create instances of concrete classes defined in the database adapter packages (for creating connections, defining database configuration, defining credentials, etc.)
@@ -0,0 +1,3 @@
1
+ from pkgutil import extend_path
2
+
3
+ __path__ = extend_path(__path__, __name__)
@@ -0,0 +1,4 @@
1
+ # Global project configuration for dvt-core
2
+ # This defines the name of the global/internal project namespace
3
+
4
+ PROJECT_NAME = "dbt" # Keep as "dbt" for compatibility with adapter ecosystem
@@ -0,0 +1,4 @@
1
+
2
+ target/
3
+ dbt_packages/
4
+ logs/
@@ -0,0 +1,15 @@
1
+ Welcome to your new dbt project!
2
+
3
+ ### Using the starter project
4
+
5
+ Try running the following commands:
6
+ - dbt run
7
+ - dbt test
8
+
9
+
10
+ ### Resources:
11
+ - Learn more about dbt [in the docs](https://docs.getdbt.com/docs/introduction)
12
+ - Check out [Discourse](https://discourse.getdbt.com/) for commonly asked questions and answers
13
+ - Join the [chat](https://community.getdbt.com/) on Slack for live discussions and support
14
+ - Find [dbt events](https://events.getdbt.com) near you
15
+ - Check out [the blog](https://blog.getdbt.com/) for the latest news on dbt's development and best practices
@@ -0,0 +1,3 @@
1
+ import os
2
+
3
+ PACKAGE_PATH = os.path.dirname(__file__)
File without changes
@@ -0,0 +1,36 @@
1
+
2
+ # Name your project! Project names should contain only lowercase characters
3
+ # and underscores. A good package name should reflect your organization's
4
+ # name or the intended use of these models
5
+ name: '{project_name}'
6
+ version: '1.0.0'
7
+
8
+ # This setting configures which "profile" dbt uses for this project.
9
+ profile: '{profile_name}'
10
+
11
+ # These configurations specify where dbt should look for different types of files.
12
+ # The `model-paths` config, for example, states that models in this project can be
13
+ # found in the "models/" directory. You probably won't need to change these!
14
+ model-paths: ["models"]
15
+ analysis-paths: ["analyses"]
16
+ test-paths: ["tests"]
17
+ seed-paths: ["seeds"]
18
+ macro-paths: ["macros"]
19
+ snapshot-paths: ["snapshots"]
20
+
21
+ clean-targets: # directories to be removed by `dbt clean`
22
+ - "target"
23
+ - "dbt_packages"
24
+
25
+
26
+ # Configuring models
27
+ # Full documentation: https://docs.getdbt.com/docs/configuring-models
28
+
29
+ # In this example config, we tell dbt to build all models in the example/
30
+ # directory as views. These settings can be overridden in the individual model
31
+ # files using the `{{{{ config(...) }}}}` macro.
32
+ models:
33
+ {project_name}:
34
+ # Config indicated by + and applies to all files under models/example/
35
+ example:
36
+ +materialized: view
File without changes
@@ -0,0 +1,27 @@
1
+
2
+ /*
3
+ Welcome to your first dbt model!
4
+ Did you know that you can also configure models directly within SQL files?
5
+ This will override configurations stated in dbt_project.yml
6
+
7
+ Try changing "table" to "view" below
8
+ */
9
+
10
+ {{ config(materialized='table') }}
11
+
12
+ with source_data as (
13
+
14
+ select 1 as id
15
+ union all
16
+ select null as id
17
+
18
+ )
19
+
20
+ select *
21
+ from source_data
22
+
23
+ /*
24
+ Uncomment the line below to remove records with null `id` values
25
+ */
26
+
27
+ -- where id is not null
@@ -0,0 +1,6 @@
1
+
2
+ -- Use the `ref` function to select from other models
3
+
4
+ select *
5
+ from {{ ref('my_first_dbt_model') }}
6
+ where id = 1
@@ -0,0 +1,21 @@
1
+
2
+ version: 2
3
+
4
+ models:
5
+ - name: my_first_dbt_model
6
+ description: "A starter dbt model"
7
+ columns:
8
+ - name: id
9
+ description: "The primary key for this table"
10
+ data_tests:
11
+ - unique
12
+ - not_null
13
+
14
+ - name: my_second_dbt_model
15
+ description: "A starter dbt model"
16
+ columns:
17
+ - name: id
18
+ description: "The primary key for this table"
19
+ data_tests:
20
+ - unique
21
+ - not_null
File without changes
File without changes
File without changes
@@ -0,0 +1,27 @@
1
+ import functools
2
+ from typing import Optional
3
+
4
+ from dvt.events.types import InternalDeprecation
5
+
6
+ from dbt_common.events.functions import warn_or_error
7
+
8
+
9
+ def deprecated(suggested_action: str, version: str, reason: Optional[str]):
10
+ def inner(func):
11
+ @functools.wraps(func)
12
+ def wrapped(*args, **kwargs):
13
+ name = func.__name__
14
+
15
+ warn_or_error(
16
+ InternalDeprecation(
17
+ name=name,
18
+ suggested_action=suggested_action,
19
+ version=version,
20
+ reason=reason,
21
+ )
22
+ ) # TODO: pass in event?
23
+ return func(*args, **kwargs)
24
+
25
+ return wrapped
26
+
27
+ return inner
@@ -0,0 +1,3 @@
1
+ import os
2
+
3
+ JSONSCHEMAS_PATH = os.path.dirname(__file__)