dvt-core 0.58.6__cp311-cp311-macosx_10_9_x86_64.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.
Files changed (324) hide show
  1. dbt/__init__.py +7 -0
  2. dbt/_pydantic_shim.py +26 -0
  3. dbt/artifacts/__init__.py +0 -0
  4. dbt/artifacts/exceptions/__init__.py +1 -0
  5. dbt/artifacts/exceptions/schemas.py +31 -0
  6. dbt/artifacts/resources/__init__.py +116 -0
  7. dbt/artifacts/resources/base.py +67 -0
  8. dbt/artifacts/resources/types.py +93 -0
  9. dbt/artifacts/resources/v1/analysis.py +10 -0
  10. dbt/artifacts/resources/v1/catalog.py +23 -0
  11. dbt/artifacts/resources/v1/components.py +274 -0
  12. dbt/artifacts/resources/v1/config.py +277 -0
  13. dbt/artifacts/resources/v1/documentation.py +11 -0
  14. dbt/artifacts/resources/v1/exposure.py +51 -0
  15. dbt/artifacts/resources/v1/function.py +52 -0
  16. dbt/artifacts/resources/v1/generic_test.py +31 -0
  17. dbt/artifacts/resources/v1/group.py +21 -0
  18. dbt/artifacts/resources/v1/hook.py +11 -0
  19. dbt/artifacts/resources/v1/macro.py +29 -0
  20. dbt/artifacts/resources/v1/metric.py +172 -0
  21. dbt/artifacts/resources/v1/model.py +145 -0
  22. dbt/artifacts/resources/v1/owner.py +10 -0
  23. dbt/artifacts/resources/v1/saved_query.py +111 -0
  24. dbt/artifacts/resources/v1/seed.py +41 -0
  25. dbt/artifacts/resources/v1/semantic_layer_components.py +72 -0
  26. dbt/artifacts/resources/v1/semantic_model.py +314 -0
  27. dbt/artifacts/resources/v1/singular_test.py +14 -0
  28. dbt/artifacts/resources/v1/snapshot.py +91 -0
  29. dbt/artifacts/resources/v1/source_definition.py +84 -0
  30. dbt/artifacts/resources/v1/sql_operation.py +10 -0
  31. dbt/artifacts/resources/v1/unit_test_definition.py +77 -0
  32. dbt/artifacts/schemas/__init__.py +0 -0
  33. dbt/artifacts/schemas/base.py +191 -0
  34. dbt/artifacts/schemas/batch_results.py +24 -0
  35. dbt/artifacts/schemas/catalog/__init__.py +11 -0
  36. dbt/artifacts/schemas/catalog/v1/__init__.py +0 -0
  37. dbt/artifacts/schemas/catalog/v1/catalog.py +59 -0
  38. dbt/artifacts/schemas/freshness/__init__.py +1 -0
  39. dbt/artifacts/schemas/freshness/v3/__init__.py +0 -0
  40. dbt/artifacts/schemas/freshness/v3/freshness.py +158 -0
  41. dbt/artifacts/schemas/manifest/__init__.py +2 -0
  42. dbt/artifacts/schemas/manifest/v12/__init__.py +0 -0
  43. dbt/artifacts/schemas/manifest/v12/manifest.py +211 -0
  44. dbt/artifacts/schemas/results.py +147 -0
  45. dbt/artifacts/schemas/run/__init__.py +2 -0
  46. dbt/artifacts/schemas/run/v5/__init__.py +0 -0
  47. dbt/artifacts/schemas/run/v5/run.py +184 -0
  48. dbt/artifacts/schemas/upgrades/__init__.py +4 -0
  49. dbt/artifacts/schemas/upgrades/upgrade_manifest.py +174 -0
  50. dbt/artifacts/schemas/upgrades/upgrade_manifest_dbt_version.py +2 -0
  51. dbt/artifacts/utils/validation.py +153 -0
  52. dbt/cli/__init__.py +1 -0
  53. dbt/cli/context.py +17 -0
  54. dbt/cli/exceptions.py +57 -0
  55. dbt/cli/flags.py +560 -0
  56. dbt/cli/main.py +2403 -0
  57. dbt/cli/option_types.py +121 -0
  58. dbt/cli/options.py +80 -0
  59. dbt/cli/params.py +844 -0
  60. dbt/cli/requires.py +490 -0
  61. dbt/cli/resolvers.py +50 -0
  62. dbt/cli/types.py +40 -0
  63. dbt/clients/__init__.py +0 -0
  64. dbt/clients/checked_load.py +83 -0
  65. dbt/clients/git.py +164 -0
  66. dbt/clients/jinja.py +206 -0
  67. dbt/clients/jinja_static.py +245 -0
  68. dbt/clients/registry.py +192 -0
  69. dbt/clients/yaml_helper.py +68 -0
  70. dbt/compilation.py +876 -0
  71. dbt/compute/__init__.py +14 -0
  72. dbt/compute/engines/__init__.py +12 -0
  73. dbt/compute/engines/spark_engine.cpython-311-darwin.so +0 -0
  74. dbt/compute/engines/spark_engine.py +642 -0
  75. dbt/compute/federated_executor.cpython-311-darwin.so +0 -0
  76. dbt/compute/federated_executor.py +1080 -0
  77. dbt/compute/filter_pushdown.cpython-311-darwin.so +0 -0
  78. dbt/compute/filter_pushdown.py +273 -0
  79. dbt/compute/jar_provisioning.cpython-311-darwin.so +0 -0
  80. dbt/compute/jar_provisioning.py +255 -0
  81. dbt/compute/java_compat.cpython-311-darwin.so +0 -0
  82. dbt/compute/java_compat.py +689 -0
  83. dbt/compute/jdbc_utils.cpython-311-darwin.so +0 -0
  84. dbt/compute/jdbc_utils.py +678 -0
  85. dbt/compute/metadata/__init__.py +40 -0
  86. dbt/compute/metadata/adapters_registry.cpython-311-darwin.so +0 -0
  87. dbt/compute/metadata/adapters_registry.py +370 -0
  88. dbt/compute/metadata/registry.cpython-311-darwin.so +0 -0
  89. dbt/compute/metadata/registry.py +674 -0
  90. dbt/compute/metadata/store.cpython-311-darwin.so +0 -0
  91. dbt/compute/metadata/store.py +1499 -0
  92. dbt/compute/smart_selector.cpython-311-darwin.so +0 -0
  93. dbt/compute/smart_selector.py +377 -0
  94. dbt/compute/strategies/__init__.py +55 -0
  95. dbt/compute/strategies/base.cpython-311-darwin.so +0 -0
  96. dbt/compute/strategies/base.py +165 -0
  97. dbt/compute/strategies/dataproc.cpython-311-darwin.so +0 -0
  98. dbt/compute/strategies/dataproc.py +207 -0
  99. dbt/compute/strategies/emr.cpython-311-darwin.so +0 -0
  100. dbt/compute/strategies/emr.py +203 -0
  101. dbt/compute/strategies/local.cpython-311-darwin.so +0 -0
  102. dbt/compute/strategies/local.py +443 -0
  103. dbt/compute/strategies/standalone.cpython-311-darwin.so +0 -0
  104. dbt/compute/strategies/standalone.py +262 -0
  105. dbt/config/__init__.py +4 -0
  106. dbt/config/catalogs.py +94 -0
  107. dbt/config/compute.cpython-311-darwin.so +0 -0
  108. dbt/config/compute.py +513 -0
  109. dbt/config/dvt_profile.cpython-311-darwin.so +0 -0
  110. dbt/config/dvt_profile.py +342 -0
  111. dbt/config/profile.py +422 -0
  112. dbt/config/project.py +873 -0
  113. dbt/config/project_utils.py +28 -0
  114. dbt/config/renderer.py +231 -0
  115. dbt/config/runtime.py +553 -0
  116. dbt/config/selectors.py +208 -0
  117. dbt/config/utils.py +77 -0
  118. dbt/constants.py +28 -0
  119. dbt/context/__init__.py +0 -0
  120. dbt/context/base.py +745 -0
  121. dbt/context/configured.py +135 -0
  122. dbt/context/context_config.py +382 -0
  123. dbt/context/docs.py +82 -0
  124. dbt/context/exceptions_jinja.py +178 -0
  125. dbt/context/macro_resolver.py +195 -0
  126. dbt/context/macros.py +171 -0
  127. dbt/context/manifest.py +72 -0
  128. dbt/context/providers.py +2249 -0
  129. dbt/context/query_header.py +13 -0
  130. dbt/context/secret.py +58 -0
  131. dbt/context/target.py +74 -0
  132. dbt/contracts/__init__.py +0 -0
  133. dbt/contracts/files.py +413 -0
  134. dbt/contracts/graph/__init__.py +0 -0
  135. dbt/contracts/graph/manifest.py +1904 -0
  136. dbt/contracts/graph/metrics.py +97 -0
  137. dbt/contracts/graph/model_config.py +70 -0
  138. dbt/contracts/graph/node_args.py +42 -0
  139. dbt/contracts/graph/nodes.py +1806 -0
  140. dbt/contracts/graph/semantic_manifest.py +232 -0
  141. dbt/contracts/graph/unparsed.py +811 -0
  142. dbt/contracts/project.py +417 -0
  143. dbt/contracts/results.py +53 -0
  144. dbt/contracts/selection.py +23 -0
  145. dbt/contracts/sql.py +85 -0
  146. dbt/contracts/state.py +68 -0
  147. dbt/contracts/util.py +46 -0
  148. dbt/deprecations.py +348 -0
  149. dbt/deps/__init__.py +0 -0
  150. dbt/deps/base.py +152 -0
  151. dbt/deps/git.py +195 -0
  152. dbt/deps/local.py +79 -0
  153. dbt/deps/registry.py +130 -0
  154. dbt/deps/resolver.py +149 -0
  155. dbt/deps/tarball.py +120 -0
  156. dbt/docs/source/_ext/dbt_click.py +119 -0
  157. dbt/docs/source/conf.py +32 -0
  158. dbt/env_vars.py +64 -0
  159. dbt/event_time/event_time.py +40 -0
  160. dbt/event_time/sample_window.py +60 -0
  161. dbt/events/__init__.py +15 -0
  162. dbt/events/base_types.py +36 -0
  163. dbt/events/core_types_pb2.py +2 -0
  164. dbt/events/logging.py +108 -0
  165. dbt/events/types.py +2516 -0
  166. dbt/exceptions.py +1486 -0
  167. dbt/flags.py +89 -0
  168. dbt/graph/__init__.py +11 -0
  169. dbt/graph/cli.py +249 -0
  170. dbt/graph/graph.py +172 -0
  171. dbt/graph/queue.py +214 -0
  172. dbt/graph/selector.py +374 -0
  173. dbt/graph/selector_methods.py +975 -0
  174. dbt/graph/selector_spec.py +222 -0
  175. dbt/graph/thread_pool.py +18 -0
  176. dbt/hooks.py +21 -0
  177. dbt/include/README.md +49 -0
  178. dbt/include/__init__.py +3 -0
  179. dbt/include/data/adapters_registry.duckdb +0 -0
  180. dbt/include/data/build_registry.py +242 -0
  181. dbt/include/data/csv/adapter_queries.csv +33 -0
  182. dbt/include/data/csv/syntax_rules.csv +9 -0
  183. dbt/include/data/csv/type_mappings_bigquery.csv +28 -0
  184. dbt/include/data/csv/type_mappings_databricks.csv +30 -0
  185. dbt/include/data/csv/type_mappings_mysql.csv +40 -0
  186. dbt/include/data/csv/type_mappings_oracle.csv +30 -0
  187. dbt/include/data/csv/type_mappings_postgres.csv +56 -0
  188. dbt/include/data/csv/type_mappings_redshift.csv +33 -0
  189. dbt/include/data/csv/type_mappings_snowflake.csv +38 -0
  190. dbt/include/data/csv/type_mappings_sqlserver.csv +35 -0
  191. dbt/include/starter_project/.gitignore +4 -0
  192. dbt/include/starter_project/README.md +15 -0
  193. dbt/include/starter_project/__init__.py +3 -0
  194. dbt/include/starter_project/analyses/.gitkeep +0 -0
  195. dbt/include/starter_project/dbt_project.yml +36 -0
  196. dbt/include/starter_project/macros/.gitkeep +0 -0
  197. dbt/include/starter_project/models/example/my_first_dbt_model.sql +27 -0
  198. dbt/include/starter_project/models/example/my_second_dbt_model.sql +6 -0
  199. dbt/include/starter_project/models/example/schema.yml +21 -0
  200. dbt/include/starter_project/seeds/.gitkeep +0 -0
  201. dbt/include/starter_project/snapshots/.gitkeep +0 -0
  202. dbt/include/starter_project/tests/.gitkeep +0 -0
  203. dbt/internal_deprecations.py +26 -0
  204. dbt/jsonschemas/__init__.py +3 -0
  205. dbt/jsonschemas/jsonschemas.py +309 -0
  206. dbt/jsonschemas/project/0.0.110.json +4717 -0
  207. dbt/jsonschemas/project/0.0.85.json +2015 -0
  208. dbt/jsonschemas/resources/0.0.110.json +2636 -0
  209. dbt/jsonschemas/resources/0.0.85.json +2536 -0
  210. dbt/jsonschemas/resources/latest.json +6773 -0
  211. dbt/links.py +4 -0
  212. dbt/materializations/__init__.py +0 -0
  213. dbt/materializations/incremental/__init__.py +0 -0
  214. dbt/materializations/incremental/microbatch.py +236 -0
  215. dbt/mp_context.py +8 -0
  216. dbt/node_types.py +37 -0
  217. dbt/parser/__init__.py +23 -0
  218. dbt/parser/analysis.py +21 -0
  219. dbt/parser/base.py +548 -0
  220. dbt/parser/common.py +266 -0
  221. dbt/parser/docs.py +52 -0
  222. dbt/parser/fixtures.py +51 -0
  223. dbt/parser/functions.py +30 -0
  224. dbt/parser/generic_test.py +100 -0
  225. dbt/parser/generic_test_builders.py +333 -0
  226. dbt/parser/hooks.py +118 -0
  227. dbt/parser/macros.py +137 -0
  228. dbt/parser/manifest.py +2204 -0
  229. dbt/parser/models.py +573 -0
  230. dbt/parser/partial.py +1178 -0
  231. dbt/parser/read_files.py +445 -0
  232. dbt/parser/schema_generic_tests.py +422 -0
  233. dbt/parser/schema_renderer.py +111 -0
  234. dbt/parser/schema_yaml_readers.py +935 -0
  235. dbt/parser/schemas.py +1466 -0
  236. dbt/parser/search.py +149 -0
  237. dbt/parser/seeds.py +28 -0
  238. dbt/parser/singular_test.py +20 -0
  239. dbt/parser/snapshots.py +44 -0
  240. dbt/parser/sources.py +558 -0
  241. dbt/parser/sql.py +62 -0
  242. dbt/parser/unit_tests.py +621 -0
  243. dbt/plugins/__init__.py +20 -0
  244. dbt/plugins/contracts.py +9 -0
  245. dbt/plugins/exceptions.py +2 -0
  246. dbt/plugins/manager.py +163 -0
  247. dbt/plugins/manifest.py +21 -0
  248. dbt/profiler.py +20 -0
  249. dbt/py.typed +1 -0
  250. dbt/query_analyzer.cpython-311-darwin.so +0 -0
  251. dbt/query_analyzer.py +410 -0
  252. dbt/runners/__init__.py +2 -0
  253. dbt/runners/exposure_runner.py +7 -0
  254. dbt/runners/no_op_runner.py +45 -0
  255. dbt/runners/saved_query_runner.py +7 -0
  256. dbt/selected_resources.py +8 -0
  257. dbt/task/__init__.py +0 -0
  258. dbt/task/base.py +503 -0
  259. dbt/task/build.py +197 -0
  260. dbt/task/clean.py +56 -0
  261. dbt/task/clone.py +161 -0
  262. dbt/task/compile.py +150 -0
  263. dbt/task/compute.cpython-311-darwin.so +0 -0
  264. dbt/task/compute.py +458 -0
  265. dbt/task/debug.py +505 -0
  266. dbt/task/deps.py +280 -0
  267. dbt/task/docs/__init__.py +3 -0
  268. dbt/task/docs/api/__init__.py +23 -0
  269. dbt/task/docs/api/catalog.cpython-311-darwin.so +0 -0
  270. dbt/task/docs/api/catalog.py +204 -0
  271. dbt/task/docs/api/lineage.cpython-311-darwin.so +0 -0
  272. dbt/task/docs/api/lineage.py +234 -0
  273. dbt/task/docs/api/profile.cpython-311-darwin.so +0 -0
  274. dbt/task/docs/api/profile.py +204 -0
  275. dbt/task/docs/api/spark.cpython-311-darwin.so +0 -0
  276. dbt/task/docs/api/spark.py +186 -0
  277. dbt/task/docs/generate.py +947 -0
  278. dbt/task/docs/index.html +250 -0
  279. dbt/task/docs/serve.cpython-311-darwin.so +0 -0
  280. dbt/task/docs/serve.py +174 -0
  281. dbt/task/dvt_output.py +362 -0
  282. dbt/task/dvt_run.py +204 -0
  283. dbt/task/freshness.py +322 -0
  284. dbt/task/function.py +121 -0
  285. dbt/task/group_lookup.py +46 -0
  286. dbt/task/init.cpython-311-darwin.so +0 -0
  287. dbt/task/init.py +604 -0
  288. dbt/task/java.cpython-311-darwin.so +0 -0
  289. dbt/task/java.py +316 -0
  290. dbt/task/list.py +236 -0
  291. dbt/task/metadata.cpython-311-darwin.so +0 -0
  292. dbt/task/metadata.py +804 -0
  293. dbt/task/printer.py +175 -0
  294. dbt/task/profile.cpython-311-darwin.so +0 -0
  295. dbt/task/profile.py +1307 -0
  296. dbt/task/profile_serve.py +615 -0
  297. dbt/task/retract.py +438 -0
  298. dbt/task/retry.py +175 -0
  299. dbt/task/run.py +1387 -0
  300. dbt/task/run_operation.py +141 -0
  301. dbt/task/runnable.py +758 -0
  302. dbt/task/seed.py +103 -0
  303. dbt/task/show.py +149 -0
  304. dbt/task/snapshot.py +56 -0
  305. dbt/task/spark.cpython-311-darwin.so +0 -0
  306. dbt/task/spark.py +414 -0
  307. dbt/task/sql.py +110 -0
  308. dbt/task/target_sync.cpython-311-darwin.so +0 -0
  309. dbt/task/target_sync.py +766 -0
  310. dbt/task/test.py +464 -0
  311. dbt/tests/fixtures/__init__.py +1 -0
  312. dbt/tests/fixtures/project.py +620 -0
  313. dbt/tests/util.py +651 -0
  314. dbt/tracking.py +529 -0
  315. dbt/utils/__init__.py +3 -0
  316. dbt/utils/artifact_upload.py +151 -0
  317. dbt/utils/utils.py +408 -0
  318. dbt/version.py +270 -0
  319. dvt_cli/__init__.py +72 -0
  320. dvt_core-0.58.6.dist-info/METADATA +288 -0
  321. dvt_core-0.58.6.dist-info/RECORD +324 -0
  322. dvt_core-0.58.6.dist-info/WHEEL +5 -0
  323. dvt_core-0.58.6.dist-info/entry_points.txt +2 -0
  324. dvt_core-0.58.6.dist-info/top_level.txt +2 -0
dbt/context/base.py ADDED
@@ -0,0 +1,745 @@
1
+ from __future__ import annotations
2
+
3
+ import datetime
4
+ import itertools
5
+ import json
6
+ import os
7
+ import re
8
+ import threading
9
+ from typing import Any, Callable, Dict, Iterable, List, Mapping, NoReturn, Optional, Set
10
+
11
+ # These modules are added to the context. Consider alternative
12
+ # approaches which will extend well to potentially many modules
13
+ import pytz
14
+
15
+ import dbt.deprecations as deprecations
16
+ import dbt.flags as flags_module
17
+ from dbt import tracking, utils
18
+ from dbt.clients.jinja import get_rendered
19
+ from dbt.clients.yaml_helper import ( # noqa: F401
20
+ Dumper,
21
+ Loader,
22
+ SafeLoader,
23
+ safe_load,
24
+ yaml,
25
+ )
26
+ from dbt.constants import DEFAULT_ENV_PLACEHOLDER, SECRET_PLACEHOLDER
27
+ from dbt.contracts.graph.nodes import Resource
28
+ from dbt.events.types import JinjaLogDebug, JinjaLogInfo
29
+ from dbt.exceptions import (
30
+ EnvVarMissingError,
31
+ RequiredVarNotFoundError,
32
+ SecretEnvVarLocationError,
33
+ SetStrictWrongTypeError,
34
+ ZipStrictWrongTypeError,
35
+ )
36
+ from dbt.flags import get_flags
37
+ from dbt.version import __version__ as dbt_version
38
+ from dbt_common.constants import SECRET_ENV_PREFIX
39
+ from dbt_common.context import get_invocation_context
40
+ from dbt_common.events.contextvars import get_node_info
41
+ from dbt_common.events.functions import fire_event, get_invocation_id
42
+ from dbt_common.events.types import PrintEvent
43
+ from dbt_common.exceptions.macros import MacroReturn
44
+
45
+ # See the `contexts` module README for more information on how contexts work
46
+
47
+
48
+ def get_pytz_module_context() -> Dict[str, Any]:
49
+ context_exports = pytz.__all__ # type: ignore
50
+
51
+ return {name: getattr(pytz, name) for name in context_exports}
52
+
53
+
54
+ def get_datetime_module_context() -> Dict[str, Any]:
55
+ context_exports = ["date", "datetime", "time", "timedelta", "tzinfo"]
56
+
57
+ return {name: getattr(datetime, name) for name in context_exports}
58
+
59
+
60
+ def get_re_module_context() -> Dict[str, Any]:
61
+ # TODO CT-211
62
+ context_exports = re.__all__ # type: ignore[attr-defined]
63
+
64
+ return {name: getattr(re, name) for name in context_exports}
65
+
66
+
67
+ def get_itertools_module_context() -> Dict[str, Any]:
68
+ # Excluded dropwhile, filterfalse, takewhile and groupby;
69
+ # first 3 illogical for Jinja and last redundant.
70
+ context_exports = [
71
+ "count",
72
+ "cycle",
73
+ "repeat",
74
+ "accumulate",
75
+ "chain",
76
+ "compress",
77
+ "islice",
78
+ "starmap",
79
+ "tee",
80
+ "zip_longest",
81
+ "product",
82
+ "permutations",
83
+ "combinations",
84
+ "combinations_with_replacement",
85
+ ]
86
+
87
+ def deprecation_wrapper(fn):
88
+ def deprecation_wrapper_inner(*args, **kwargs):
89
+ deprecations.warn("modules-itertools-usage-deprecation")
90
+ return fn(*args, **kwargs)
91
+
92
+ return deprecation_wrapper_inner
93
+
94
+ return {name: deprecation_wrapper(getattr(itertools, name)) for name in context_exports}
95
+
96
+
97
+ def get_context_modules() -> Dict[str, Dict[str, Any]]:
98
+ return {
99
+ "pytz": get_pytz_module_context(),
100
+ "datetime": get_datetime_module_context(),
101
+ "re": get_re_module_context(),
102
+ "itertools": get_itertools_module_context(),
103
+ }
104
+
105
+
106
+ class ContextMember:
107
+ def __init__(self, value: Any, name: Optional[str] = None) -> None:
108
+ self.name = name
109
+ self.inner = value
110
+
111
+ def key(self, default: str) -> str:
112
+ if self.name is None:
113
+ return default
114
+ return self.name
115
+
116
+
117
+ def contextmember(value: Optional[str] = None) -> Callable:
118
+ return lambda v: ContextMember(v, name=value)
119
+
120
+
121
+ def contextproperty(value: Optional[str] = None) -> Callable:
122
+ return lambda v: ContextMember(property(v), name=value)
123
+
124
+
125
+ class ContextMeta(type):
126
+ def __new__(mcls, name, bases, dct: Dict[str, Any]) -> ContextMeta:
127
+ context_members: Dict[str, Any] = {}
128
+ context_attrs: Dict[str, Any] = {}
129
+ new_dct: Dict[str, Any] = {}
130
+
131
+ for base in bases:
132
+ context_members.update(getattr(base, "_context_members_", {}))
133
+ context_attrs.update(getattr(base, "_context_attrs_", {}))
134
+
135
+ for key, value in dct.items():
136
+ if isinstance(value, ContextMember):
137
+ context_key = value.key(key)
138
+ context_members[context_key] = value.inner
139
+ context_attrs[context_key] = key
140
+ value = value.inner
141
+ new_dct[key] = value
142
+ new_dct["_context_members_"] = context_members
143
+ new_dct["_context_attrs_"] = context_attrs
144
+ return type.__new__(mcls, name, bases, new_dct)
145
+
146
+
147
+ class Var:
148
+ _VAR_NOTSET = object()
149
+
150
+ def __init__(
151
+ self,
152
+ context: Mapping[str, Any],
153
+ cli_vars: Mapping[str, Any],
154
+ node: Optional[Resource] = None,
155
+ ) -> None:
156
+ self._context: Mapping[str, Any] = context
157
+ self._cli_vars: Mapping[str, Any] = cli_vars
158
+ self._node: Optional[Resource] = node
159
+ self._merged: Mapping[str, Any] = self._generate_merged()
160
+
161
+ def _generate_merged(self) -> Mapping[str, Any]:
162
+ return self._cli_vars
163
+
164
+ @property
165
+ def node_name(self) -> str:
166
+ if self._node is not None:
167
+ return self._node.name
168
+ else:
169
+ return "<Configuration>"
170
+
171
+ def get_missing_var(self, var_name: str) -> NoReturn:
172
+ # TODO function name implies a non exception resolution
173
+ raise RequiredVarNotFoundError(var_name, dict(self._merged), self._node)
174
+
175
+ def has_var(self, var_name: str) -> bool:
176
+ return var_name in self._merged
177
+
178
+ def get_rendered_var(self, var_name: str) -> Any:
179
+ raw = self._merged[var_name]
180
+ # if bool/int/float/etc are passed in, don't compile anything
181
+ if not isinstance(raw, str):
182
+ return raw
183
+
184
+ return get_rendered(raw, dict(self._context))
185
+
186
+ def __call__(self, var_name: str, default: Any = _VAR_NOTSET) -> Any:
187
+ if self.has_var(var_name):
188
+ return self.get_rendered_var(var_name)
189
+ elif default is not self._VAR_NOTSET:
190
+ return default
191
+ else:
192
+ return self.get_missing_var(var_name)
193
+
194
+
195
+ class BaseContext(metaclass=ContextMeta):
196
+ # Set by ContextMeta
197
+ _context_members_: Dict[str, Any]
198
+ _context_attrs_: Dict[str, Any]
199
+
200
+ # subclass is TargetContext
201
+ def __init__(self, cli_vars: Dict[str, Any]) -> None:
202
+ self._ctx: Dict[str, Any] = {}
203
+ self.cli_vars: Dict[str, Any] = cli_vars
204
+ self.env_vars: Dict[str, Any] = {}
205
+
206
+ def generate_builtins(self) -> Dict[str, Any]:
207
+ builtins: Dict[str, Any] = {}
208
+ for key, value in self._context_members_.items():
209
+ if hasattr(value, "__get__"):
210
+ # handle properties, bound methods, etc
211
+ value = value.__get__(self)
212
+ builtins[key] = value
213
+ return builtins
214
+
215
+ # no dbtClassMixin so this is not an actual override
216
+ def to_dict(self) -> Dict[str, Any]:
217
+ self._ctx["context"] = self._ctx
218
+ builtins = self.generate_builtins()
219
+ self._ctx["builtins"] = builtins
220
+ self._ctx.update(builtins)
221
+ return self._ctx
222
+
223
+ @contextproperty()
224
+ def dbt_version(self) -> str:
225
+ """The `dbt_version` variable returns the installed version of dbt that
226
+ is currently running. It can be used for debugging or auditing
227
+ purposes.
228
+
229
+ > macros/get_version.sql
230
+
231
+ {% macro get_version() %}
232
+ {% set msg = "The installed version of dbt is: " ~ dbt_version %}
233
+ {% do log(msg, info=true) %}
234
+ {% endmacro %}
235
+
236
+ Example output:
237
+
238
+ $ dbt run-operation get_version
239
+ The installed version of dbt is 0.16.0
240
+ """
241
+ return dbt_version
242
+
243
+ @contextproperty()
244
+ def var(self) -> Var:
245
+ """Variables can be passed from your `dbt_project.yml` file into models
246
+ during compilation. These variables are useful for configuring packages
247
+ for deployment in multiple environments, or defining values that should
248
+ be used across multiple models within a package.
249
+
250
+ To add a variable to a model, use the `var()` function:
251
+
252
+ > my_model.sql:
253
+
254
+ select * from events where event_type = '{{ var("event_type") }}'
255
+
256
+ If you try to run this model without supplying an `event_type`
257
+ variable, you'll receive a compilation error that looks like this:
258
+
259
+ Encountered an error:
260
+ ! Compilation error while compiling model package_name.my_model:
261
+ ! Required var 'event_type' not found in config:
262
+ Vars supplied to package_name.my_model = {
263
+ }
264
+
265
+ To supply a variable to a given model, add one or more `vars`
266
+ dictionaries to the `models` config in your `dbt_project.yml` file.
267
+ These `vars` are in-scope for all models at or below where they are
268
+ defined, so place them where they make the most sense. Below are three
269
+ different placements of the `vars` dict, all of which will make the
270
+ `my_model` model compile.
271
+
272
+ > dbt_project.yml:
273
+
274
+ # 1) scoped at the model level
275
+ models:
276
+ package_name:
277
+ my_model:
278
+ materialized: view
279
+ vars:
280
+ event_type: activation
281
+ # 2) scoped at the package level
282
+ models:
283
+ package_name:
284
+ vars:
285
+ event_type: activation
286
+ my_model:
287
+ materialized: view
288
+ # 3) scoped globally
289
+ models:
290
+ vars:
291
+ event_type: activation
292
+ package_name:
293
+ my_model:
294
+ materialized: view
295
+
296
+ ## Variable default values
297
+
298
+ The `var()` function takes an optional second argument, `default`. If
299
+ this argument is provided, then it will be the default value for the
300
+ variable if one is not explicitly defined.
301
+
302
+ > my_model.sql:
303
+
304
+ -- Use 'activation' as the event_type if the variable is not
305
+ -- defined.
306
+ select *
307
+ from events
308
+ where event_type = '{{ var("event_type", "activation") }}'
309
+ """
310
+ return Var(self._ctx, self.cli_vars)
311
+
312
+ @contextmember()
313
+ def env_var(self, var: str, default: Optional[str] = None) -> str:
314
+ """The env_var() function. Return the environment variable named 'var'.
315
+ If there is no such environment variable set, return the default.
316
+
317
+ If the default is None, raise an exception for an undefined variable.
318
+ """
319
+ return_value = None
320
+ if var.startswith(SECRET_ENV_PREFIX):
321
+ raise SecretEnvVarLocationError(var)
322
+ env = get_invocation_context().env
323
+ if var in env:
324
+ return_value = env[var]
325
+ elif default is not None:
326
+ return_value = default
327
+
328
+ if return_value is not None:
329
+ # If the environment variable is set from a default, store a string indicating
330
+ # that so we can skip partial parsing. Otherwise the file will be scheduled for
331
+ # reparsing. If the default changes, the file will have been updated and therefore
332
+ # will be scheduled for reparsing anyways.
333
+ self.env_vars[var] = return_value if var in env else DEFAULT_ENV_PLACEHOLDER
334
+
335
+ return return_value
336
+ else:
337
+ raise EnvVarMissingError(var)
338
+
339
+ if os.environ.get("DBT_MACRO_DEBUGGING"):
340
+
341
+ @contextmember()
342
+ @staticmethod
343
+ def debug():
344
+ """Enter a debugger at this line in the compiled jinja code."""
345
+ import sys
346
+
347
+ import ipdb # type: ignore
348
+
349
+ frame = sys._getframe(3)
350
+ ipdb.set_trace(frame)
351
+ return ""
352
+
353
+ @contextmember("return")
354
+ @staticmethod
355
+ def _return(data: Any) -> NoReturn:
356
+ """The `return` function can be used in macros to return data to the
357
+ caller. The type of the data (`dict`, `list`, `int`, etc) will be
358
+ preserved through the return call.
359
+
360
+ :param data: The data to return to the caller
361
+
362
+
363
+ > macros/example.sql:
364
+
365
+ {% macro get_data() %}
366
+ {{ return([1,2,3]) }}
367
+ {% endmacro %}
368
+
369
+ > models/my_model.sql:
370
+
371
+ select
372
+ -- getdata() returns a list!
373
+ {% for i in getdata() %}
374
+ {{ i }}
375
+ {% if not loop.last %},{% endif %}
376
+ {% endfor %}
377
+
378
+ """
379
+ raise MacroReturn(data)
380
+
381
+ @contextmember()
382
+ @staticmethod
383
+ def fromjson(string: str, default: Any = None) -> Any:
384
+ """The `fromjson` context method can be used to deserialize a json
385
+ string into a Python object primitive, eg. a `dict` or `list`.
386
+
387
+ :param value: The json string to deserialize
388
+ :param default: A default value to return if the `string` argument
389
+ cannot be deserialized (optional)
390
+
391
+ Usage:
392
+
393
+ {% set my_json_str = '{"abc": 123}' %}
394
+ {% set my_dict = fromjson(my_json_str) %}
395
+ {% do log(my_dict['abc']) %}
396
+ """
397
+ try:
398
+ return json.loads(string)
399
+ except ValueError:
400
+ return default
401
+
402
+ @contextmember()
403
+ @staticmethod
404
+ def tojson(value: Any, default: Any = None, sort_keys: bool = False) -> Any:
405
+ """The `tojson` context method can be used to serialize a Python
406
+ object primitive, eg. a `dict` or `list` to a json string.
407
+
408
+ :param value: The value serialize to json
409
+ :param default: A default value to return if the `value` argument
410
+ cannot be serialized
411
+ :param sort_keys: If True, sort the keys.
412
+
413
+
414
+ Usage:
415
+
416
+ {% set my_dict = {"abc": 123} %}
417
+ {% set my_json_string = tojson(my_dict) %}
418
+ {% do log(my_json_string) %}
419
+ """
420
+ try:
421
+ return json.dumps(value, sort_keys=sort_keys)
422
+ except ValueError:
423
+ return default
424
+
425
+ @contextmember()
426
+ @staticmethod
427
+ def fromyaml(value: str, default: Any = None) -> Any:
428
+ """The fromyaml context method can be used to deserialize a yaml string
429
+ into a Python object primitive, eg. a `dict` or `list`.
430
+
431
+ :param value: The yaml string to deserialize
432
+ :param default: A default value to return if the `string` argument
433
+ cannot be deserialized (optional)
434
+
435
+ Usage:
436
+
437
+ {% set my_yml_str -%}
438
+ dogs:
439
+ - good
440
+ - bad
441
+ {%- endset %}
442
+ {% set my_dict = fromyaml(my_yml_str) %}
443
+ {% do log(my_dict['dogs'], info=true) %}
444
+ -- ["good", "bad"]
445
+ {% do my_dict['dogs'].pop() }
446
+ {% do log(my_dict['dogs'], info=true) %}
447
+ -- ["good"]
448
+ """
449
+ try:
450
+ return safe_load(value)
451
+ except (AttributeError, ValueError, yaml.YAMLError):
452
+ return default
453
+
454
+ # safe_dump defaults to sort_keys=True, but we act like json.dumps (the
455
+ # opposite)
456
+ @contextmember()
457
+ @staticmethod
458
+ def toyaml(
459
+ value: Any, default: Optional[str] = None, sort_keys: bool = False
460
+ ) -> Optional[str]:
461
+ """The `tojson` context method can be used to serialize a Python
462
+ object primitive, eg. a `dict` or `list` to a yaml string.
463
+
464
+ :param value: The value serialize to yaml
465
+ :param default: A default value to return if the `value` argument
466
+ cannot be serialized
467
+ :param sort_keys: If True, sort the keys.
468
+
469
+
470
+ Usage:
471
+
472
+ {% set my_dict = {"abc": 123} %}
473
+ {% set my_yaml_string = toyaml(my_dict) %}
474
+ {% do log(my_yaml_string) %}
475
+ """
476
+ try:
477
+ return yaml.safe_dump(data=value, sort_keys=sort_keys)
478
+ except (ValueError, yaml.YAMLError):
479
+ return default
480
+
481
+ @contextmember("set")
482
+ @staticmethod
483
+ def _set(value: Iterable[Any], default: Any = None) -> Optional[Set[Any]]:
484
+ """The `set` context method can be used to convert any iterable
485
+ to a sequence of iterable elements that are unique (a set).
486
+
487
+ :param value: The iterable
488
+ :param default: A default value to return if the `value` argument
489
+ is not an iterable
490
+
491
+ Usage:
492
+ {% set my_list = [1, 2, 2, 3] %}
493
+ {% set my_set = set(my_list) %}
494
+ {% do log(my_set) %} {# {1, 2, 3} #}
495
+ """
496
+ try:
497
+ return set(value)
498
+ except TypeError:
499
+ return default
500
+
501
+ @contextmember()
502
+ @staticmethod
503
+ def set_strict(value: Iterable[Any]) -> Set[Any]:
504
+ """The `set_strict` context method can be used to convert any iterable
505
+ to a sequence of iterable elements that are unique (a set). The
506
+ difference to the `set` context method is that the `set_strict` method
507
+ will raise an exception on a TypeError.
508
+
509
+ :param value: The iterable
510
+
511
+ Usage:
512
+ {% set my_list = [1, 2, 2, 3] %}
513
+ {% set my_set = set_strict(my_list) %}
514
+ {% do log(my_set) %} {# {1, 2, 3} #}
515
+ """
516
+ try:
517
+ return set(value)
518
+ except TypeError as e:
519
+ raise SetStrictWrongTypeError(e)
520
+
521
+ @contextmember("zip")
522
+ @staticmethod
523
+ def _zip(*args: Iterable[Any], default: Any = None) -> Optional[Iterable[Any]]:
524
+ """The `zip` context method can be used to used to return
525
+ an iterator of tuples, where the i-th tuple contains the i-th
526
+ element from each of the argument iterables.
527
+
528
+ :param *args: Any number of iterables
529
+ :param default: A default value to return if `*args` is not
530
+ iterable
531
+
532
+ Usage:
533
+ {% set my_list_a = [1, 2] %}
534
+ {% set my_list_b = ['alice', 'bob'] %}
535
+ {% set my_zip = zip(my_list_a, my_list_b) | list %}
536
+ {% do log(my_set) %} {# [(1, 'alice'), (2, 'bob')] #}
537
+ """
538
+ try:
539
+ return zip(*args)
540
+ except TypeError:
541
+ return default
542
+
543
+ @contextmember()
544
+ @staticmethod
545
+ def zip_strict(*args: Iterable[Any]) -> Iterable[Any]:
546
+ """The `zip_strict` context method can be used to used to return
547
+ an iterator of tuples, where the i-th tuple contains the i-th
548
+ element from each of the argument iterables. The difference to the
549
+ `zip` context method is that the `zip_strict` method will raise an
550
+ exception on a TypeError.
551
+
552
+ :param *args: Any number of iterables
553
+
554
+ Usage:
555
+ {% set my_list_a = [1, 2] %}
556
+ {% set my_list_b = ['alice', 'bob'] %}
557
+ {% set my_zip = zip_strict(my_list_a, my_list_b) | list %}
558
+ {% do log(my_set) %} {# [(1, 'alice'), (2, 'bob')] #}
559
+ """
560
+ try:
561
+ return zip(*args)
562
+ except TypeError as e:
563
+ raise ZipStrictWrongTypeError(e)
564
+
565
+ @contextmember()
566
+ @staticmethod
567
+ def log(msg: str, info: bool = False) -> str:
568
+ """Logs a line to either the log file or stdout.
569
+
570
+ :param msg: The message to log
571
+ :param info: If `False`, write to the log file. If `True`, write to
572
+ both the log file and stdout.
573
+
574
+ > macros/my_log_macro.sql
575
+
576
+ {% macro some_macro(arg1, arg2) %}
577
+ {{ log("Running some_macro: " ~ arg1 ~ ", " ~ arg2) }}
578
+ {% endmacro %}"
579
+ """
580
+ # Detect instances of the placeholder value ($$$DBT_SECRET_START...DBT_SECRET_END$$$)
581
+ # and replace it with the standard mask '*****'
582
+ if "DBT_SECRET_START" in str(msg):
583
+ search_group = f"({SECRET_ENV_PREFIX}(.*))"
584
+ pattern = SECRET_PLACEHOLDER.format(search_group).replace("$", r"\$")
585
+ m = re.search(
586
+ pattern,
587
+ msg,
588
+ )
589
+ if m:
590
+ msg = re.sub(pattern, "*****", msg)
591
+
592
+ if info:
593
+ fire_event(JinjaLogInfo(msg=msg, node_info=get_node_info()))
594
+ else:
595
+ fire_event(JinjaLogDebug(msg=msg, node_info=get_node_info()))
596
+ return ""
597
+
598
+ @contextproperty()
599
+ def run_started_at(self) -> Optional[datetime.datetime]:
600
+ """`run_started_at` outputs the timestamp that this run started, e.g.
601
+ `2017-04-21 01:23:45.678`. The `run_started_at` variable is a Python
602
+ `datetime` object. As of 0.9.1, the timezone of this variable defaults
603
+ to UTC.
604
+
605
+ > run_started_at_example.sql
606
+
607
+ select
608
+ '{{ run_started_at.strftime("%Y-%m-%d") }}' as date_day
609
+ from ...
610
+
611
+
612
+ To modify the timezone of this variable, use the the `pytz` module:
613
+
614
+ > run_started_at_utc.sql
615
+
616
+ {% set est = modules.pytz.timezone("America/New_York") %}
617
+ select
618
+ '{{ run_started_at.astimezone(est) }}' as run_started_est
619
+ from ...
620
+ """
621
+ if tracking.active_user is not None:
622
+ return tracking.active_user.run_started_at
623
+ else:
624
+ return None
625
+
626
+ @contextproperty()
627
+ def invocation_id(self) -> Optional[str]:
628
+ """invocation_id outputs a UUID generated for this dbt run (useful for
629
+ auditing)
630
+ """
631
+ return get_invocation_id()
632
+
633
+ @contextproperty()
634
+ def thread_id(self) -> str:
635
+ """thread_id outputs an ID for the current thread (useful for auditing)"""
636
+ return threading.current_thread().name
637
+
638
+ @contextproperty()
639
+ def modules(self) -> Dict[str, Any]:
640
+ """The `modules` variable in the Jinja context contains useful Python
641
+ modules for operating on data.
642
+
643
+ # datetime
644
+
645
+ This variable is a pointer to the Python datetime module.
646
+
647
+ Usage:
648
+
649
+ {% set dt = modules.datetime.datetime.now() %}
650
+
651
+ # pytz
652
+
653
+ This variable is a pointer to the Python pytz module.
654
+
655
+ Usage:
656
+
657
+ {% set dt = modules.datetime.datetime(2002, 10, 27, 6, 0, 0) %}
658
+ {% set dt_local = modules.pytz.timezone('US/Eastern').localize(dt) %}
659
+ {{ dt_local }}
660
+ """ # noqa
661
+ return get_context_modules()
662
+
663
+ @contextproperty()
664
+ def flags(self) -> Any:
665
+ """The `flags` variable contains true/false values for flags provided
666
+ on the command line.
667
+
668
+ > flags.sql:
669
+
670
+ {% if flags.FULL_REFRESH %}
671
+ drop table ...
672
+ {% else %}
673
+ -- no-op
674
+ {% endif %}
675
+
676
+ This supports all flags defined in flags submodule (core/dbt/flags.py)
677
+ """
678
+ return flags_module.get_flag_obj()
679
+
680
+ @contextmember()
681
+ @staticmethod
682
+ def print(msg: str) -> str:
683
+ """Prints a line to stdout.
684
+
685
+ :param msg: The message to print
686
+
687
+ > macros/my_log_macro.sql
688
+
689
+ {% macro some_macro(arg1, arg2) %}
690
+ {{ print("Running some_macro: " ~ arg1 ~ ", " ~ arg2) }}
691
+ {% endmacro %}"
692
+ """
693
+
694
+ if get_flags().PRINT:
695
+ # No formatting, still get to stdout when --quiet is used
696
+ fire_event(PrintEvent(msg=msg))
697
+ return ""
698
+
699
+ @contextmember()
700
+ @staticmethod
701
+ def diff_of_two_dicts(
702
+ dict_a: Dict[str, List[str]], dict_b: Dict[str, List[str]]
703
+ ) -> Dict[str, List[str]]:
704
+ """
705
+ Given two dictionaries of type Dict[str, List[str]]:
706
+ dict_a = {'key_x': ['value_1', 'VALUE_2'], 'KEY_Y': ['value_3']}
707
+ dict_b = {'key_x': ['value_1'], 'key_z': ['value_4']}
708
+ Return the same dictionary representation of dict_a MINUS dict_b,
709
+ performing a case-insensitive comparison between the strings in each.
710
+ All keys returned will be in the original case of dict_a.
711
+ returns {'key_x': ['VALUE_2'], 'KEY_Y': ['value_3']}
712
+ """
713
+
714
+ dict_diff = {}
715
+ dict_b_lowered = {k.casefold(): [x.casefold() for x in v] for k, v in dict_b.items()}
716
+ for k in dict_a:
717
+ if k.casefold() in dict_b_lowered.keys():
718
+ diff = []
719
+ for v in dict_a[k]:
720
+ if v.casefold() not in dict_b_lowered[k.casefold()]:
721
+ diff.append(v)
722
+ if diff:
723
+ dict_diff.update({k: diff})
724
+ else:
725
+ dict_diff.update({k: dict_a[k]})
726
+ return dict_diff
727
+
728
+ @contextmember()
729
+ @staticmethod
730
+ def local_md5(value: str) -> str:
731
+ """Calculates an MD5 hash of the given string.
732
+ It's called "local_md5" to emphasize that it runs locally in dbt (in jinja context) and not an MD5 SQL command.
733
+
734
+ :param value: The value to hash
735
+
736
+ Usage:
737
+ {% set value_hash = local_md5("hello world") %}
738
+ """
739
+ return utils.md5(value)
740
+
741
+
742
+ def generate_base_context(cli_vars: Dict[str, Any]) -> Dict[str, Any]:
743
+ ctx = BaseContext(cli_vars)
744
+ # This is not a Mashumaro to_dict call
745
+ return ctx.to_dict()