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/config/runtime.py ADDED
@@ -0,0 +1,553 @@
1
+ import itertools
2
+ import os
3
+ from copy import deepcopy
4
+ from dataclasses import dataclass
5
+ from pathlib import Path
6
+ from typing import (
7
+ Any,
8
+ Dict,
9
+ Iterable,
10
+ Iterator,
11
+ Mapping,
12
+ MutableSet,
13
+ Optional,
14
+ Tuple,
15
+ Type,
16
+ )
17
+
18
+ from dbt import tracking
19
+ from dbt.adapters.contracts.connection import (
20
+ AdapterRequiredConfig,
21
+ Credentials,
22
+ HasCredentials,
23
+ )
24
+ from dbt.adapters.contracts.relation import ComponentName
25
+ from dbt.adapters.factory import get_include_paths, get_relation_class_by_name
26
+ from dbt.artifacts.resources import Quoting
27
+ from dbt.config.project import load_raw_project
28
+ from dbt.contracts.graph.manifest import ManifestMetadata
29
+ from dbt.contracts.project import Configuration
30
+ from dbt.events.types import UnusedResourceConfigPath
31
+ from dbt.exceptions import (
32
+ ConfigContractBrokenError,
33
+ DbtProjectError,
34
+ DbtRuntimeError,
35
+ NonUniquePackageNameError,
36
+ UninstalledPackagesFoundError,
37
+ )
38
+ from dbt.flags import get_flags
39
+ from dbt_common.dataclass_schema import ValidationError
40
+ from dbt_common.events.functions import warn_or_error
41
+ from dbt_common.helper_types import DictDefaultEmptyStr, FQNPath, PathSet
42
+
43
+ from .profile import Profile
44
+ from .dvt_profile import DVTProfile # DVT: Multi-connection support
45
+ from .project import Project
46
+ from .renderer import DbtProjectYamlRenderer, ProfileRenderer
47
+
48
+
49
+ # Called by RuntimeConfig.collect_parts class method
50
+ def load_project(
51
+ project_root: str,
52
+ version_check: bool,
53
+ profile: HasCredentials,
54
+ cli_vars: Optional[Dict[str, Any]] = None,
55
+ validate: bool = False,
56
+ ) -> Project:
57
+ # get the project with all of the provided information
58
+ project_renderer = DbtProjectYamlRenderer(profile, cli_vars)
59
+ project = Project.from_project_root(
60
+ project_root, project_renderer, verify_version=version_check, validate=validate
61
+ )
62
+
63
+ # Save env_vars encountered in rendering for partial parsing
64
+ project.project_env_vars = project_renderer.ctx_obj.env_vars
65
+ return project
66
+
67
+
68
+ def load_profile(
69
+ project_root: str,
70
+ cli_vars: Dict[str, Any],
71
+ profile_name_override: Optional[str] = None,
72
+ target_override: Optional[str] = None,
73
+ threads_override: Optional[int] = None,
74
+ ) -> DVTProfile: # DVT: Return DVTProfile instead of Profile
75
+ raw_project = load_raw_project(project_root)
76
+ raw_profile_name = raw_project.get("profile")
77
+ profile_renderer = ProfileRenderer(cli_vars)
78
+ profile_name = profile_renderer.render_value(raw_profile_name)
79
+ # DVT: Use DVTProfile.render instead of Profile.render
80
+ profile = DVTProfile.render(
81
+ profile_renderer, profile_name, profile_name_override, target_override, threads_override
82
+ )
83
+ # Save env_vars encountered in rendering for partial parsing
84
+ profile.profile_env_vars = profile_renderer.ctx_obj.env_vars
85
+ return profile
86
+
87
+
88
+ def _project_quoting_dict(proj: Project, profile: Profile) -> Dict[ComponentName, bool]:
89
+ src: Dict[str, Any] = profile.credentials.translate_aliases(proj.quoting)
90
+ result: Dict[ComponentName, bool] = {}
91
+ for key in ComponentName:
92
+ if key in src:
93
+ value = src[key]
94
+ if isinstance(value, bool):
95
+ result[key] = value
96
+ return result
97
+
98
+
99
+ @dataclass
100
+ class RuntimeConfig(Project, Profile, AdapterRequiredConfig):
101
+ args: Any
102
+ profile_name: str
103
+ cli_vars: Dict[str, Any]
104
+ dependencies: Optional[Mapping[str, "RuntimeConfig"]] = None
105
+ # DVT: Add adapter registry for multi-connection support
106
+ adapters: Optional[Dict[str, Any]] = None # Dict[connection_name, BaseAdapter]
107
+ outputs: Optional[Dict[str, Any]] = None # Multi-connection outputs from DVTProfile
108
+
109
+ def __post_init__(self):
110
+ self.validate()
111
+ # DVT: Eagerly register all adapters from outputs
112
+ if hasattr(self, 'outputs') and self.outputs:
113
+ self.adapters = {}
114
+ # Register all adapters up-front for federated execution
115
+ for connection_name in self.outputs.keys():
116
+ try:
117
+ self._register_connection_adapter(connection_name)
118
+ except Exception:
119
+ # Adapter registration can fail (missing dependencies, etc.)
120
+ # We'll handle errors when adapter is actually used
121
+ pass
122
+
123
+ def _register_connection_adapter(self, connection_name: str):
124
+ """Lazily register and return adapter for a specific connection."""
125
+ from dbt.adapters.factory import get_adapter, register_adapter
126
+ from dbt.mp_context import get_mp_context
127
+ from copy import copy
128
+
129
+ if connection_name not in self.outputs:
130
+ raise DbtRuntimeError(
131
+ f"Connection '{connection_name}' not found in outputs. "
132
+ f"Available: {list(self.outputs.keys())}"
133
+ )
134
+
135
+ credentials = self.outputs[connection_name]
136
+
137
+ # Create a config proxy that inherits from this RuntimeConfig
138
+ # but uses different credentials
139
+ config_proxy = copy(self)
140
+ config_proxy.credentials = credentials
141
+ config_proxy.target_name = connection_name
142
+
143
+ # Register and get adapter for this connection
144
+ register_adapter(config_proxy, get_mp_context())
145
+ adapter = get_adapter(config_proxy)
146
+ self.adapters[connection_name] = adapter
147
+ return adapter
148
+
149
+ def get_adapter(self, connection_name: Optional[str] = None):
150
+ """Get adapter for a specific connection (with lazy initialization)."""
151
+ if not connection_name:
152
+ # Return default adapter
153
+ from dbt.adapters.factory import get_adapter
154
+ return get_adapter(self)
155
+
156
+ # Check if we have outputs (multi-connection mode)
157
+ if self.outputs and connection_name in self.outputs:
158
+ # Check if adapter already registered
159
+ if self.adapters and connection_name in self.adapters:
160
+ return self.adapters[connection_name]
161
+ else:
162
+ # Lazily register the adapter
163
+ return self._register_connection_adapter(connection_name)
164
+
165
+ # Fallback to default
166
+ from dbt.adapters.factory import get_adapter
167
+ return get_adapter(self)
168
+
169
+ @classmethod
170
+ def get_profile(
171
+ cls,
172
+ project_root: str,
173
+ cli_vars: Dict[str, Any],
174
+ args: Any,
175
+ ) -> Profile:
176
+ return load_profile(
177
+ project_root,
178
+ cli_vars,
179
+ args.profile,
180
+ args.target,
181
+ args.threads,
182
+ )
183
+
184
+ # Called by 'new_project' and 'from_args'
185
+ @classmethod
186
+ def from_parts(
187
+ cls,
188
+ project: Project,
189
+ profile: Profile,
190
+ args: Any,
191
+ dependencies: Optional[Mapping[str, "RuntimeConfig"]] = None,
192
+ ) -> "RuntimeConfig":
193
+ """Instantiate a RuntimeConfig from its components.
194
+
195
+ :param profile: A parsed dbt Profile.
196
+ :param project: A parsed dbt Project.
197
+ :param args: The parsed command-line arguments.
198
+ :returns RuntimeConfig: The new configuration.
199
+ """
200
+ quoting: Dict[str, Any] = (
201
+ get_relation_class_by_name(profile.credentials.type)
202
+ .get_default_quote_policy()
203
+ .replace_dict(_project_quoting_dict(project, profile))
204
+ ).to_dict(omit_none=True)
205
+
206
+ cli_vars: Dict[str, Any] = getattr(args, "vars", {})
207
+ log_cache_events: bool = getattr(args, "log_cache_events", profile.log_cache_events)
208
+
209
+ return cls(
210
+ project_name=project.project_name,
211
+ version=project.version,
212
+ project_root=project.project_root,
213
+ model_paths=project.model_paths,
214
+ macro_paths=project.macro_paths,
215
+ seed_paths=project.seed_paths,
216
+ test_paths=project.test_paths,
217
+ analysis_paths=project.analysis_paths,
218
+ docs_paths=project.docs_paths,
219
+ asset_paths=project.asset_paths,
220
+ function_paths=project.function_paths,
221
+ target_path=project.target_path,
222
+ snapshot_paths=project.snapshot_paths,
223
+ clean_targets=project.clean_targets,
224
+ log_path=project.log_path,
225
+ packages_install_path=project.packages_install_path,
226
+ packages_specified_path=project.packages_specified_path,
227
+ quoting=quoting,
228
+ models=project.models,
229
+ on_run_start=project.on_run_start,
230
+ on_run_end=project.on_run_end,
231
+ dispatch=project.dispatch,
232
+ seeds=project.seeds,
233
+ snapshots=project.snapshots,
234
+ dbt_version=project.dbt_version,
235
+ packages=project.packages,
236
+ manifest_selectors=project.manifest_selectors,
237
+ selectors=project.selectors,
238
+ query_comment=project.query_comment,
239
+ sources=project.sources,
240
+ data_tests=project.data_tests,
241
+ unit_tests=project.unit_tests,
242
+ metrics=project.metrics,
243
+ semantic_models=project.semantic_models,
244
+ saved_queries=project.saved_queries,
245
+ exposures=project.exposures,
246
+ functions=project.functions,
247
+ vars=project.vars,
248
+ config_version=project.config_version,
249
+ unrendered=project.unrendered,
250
+ project_env_vars=project.project_env_vars,
251
+ restrict_access=project.restrict_access,
252
+ profile_env_vars=profile.profile_env_vars,
253
+ profile_name=profile.profile_name,
254
+ target_name=profile.target_name,
255
+ threads=profile.threads,
256
+ credentials=profile.credentials,
257
+ args=args,
258
+ cli_vars=cli_vars,
259
+ log_cache_events=log_cache_events,
260
+ dependencies=dependencies,
261
+ dbt_cloud=project.dbt_cloud,
262
+ flags=project.flags,
263
+ outputs=getattr(profile, 'outputs', None), # DVT: Pass multi-connection outputs
264
+ )
265
+
266
+ # Called by 'load_projects' in this class
267
+ def new_project(self, project_root: str) -> "RuntimeConfig":
268
+ """Given a new project root, read in its project dictionary, supply the
269
+ existing project's profile info, and create a new project file.
270
+
271
+ :param project_root: A filepath to a dbt project.
272
+ :raises DbtProfileError: If the profile is invalid.
273
+ :raises DbtProjectError: If project is missing or invalid.
274
+ :returns: The new configuration.
275
+ """
276
+ # copy profile
277
+ profile = Profile(**self.to_profile_info())
278
+ profile.validate()
279
+
280
+ # load the new project and its packages. Don't pass cli variables.
281
+ renderer = DbtProjectYamlRenderer(profile)
282
+ project = Project.from_project_root(
283
+ project_root,
284
+ renderer,
285
+ verify_version=bool(getattr(self.args, "VERSION_CHECK", True)),
286
+ )
287
+
288
+ runtime_config = self.from_parts(
289
+ project=project,
290
+ profile=profile,
291
+ args=deepcopy(self.args),
292
+ )
293
+ # force our quoting back onto the new project.
294
+ runtime_config.quoting = deepcopy(self.quoting)
295
+ return runtime_config
296
+
297
+ def serialize(self) -> Dict[str, Any]:
298
+ """Serialize the full configuration to a single dictionary. For any
299
+ instance that has passed validate() (which happens in __init__), it
300
+ matches the Configuration contract.
301
+
302
+ Note that args are not serialized.
303
+
304
+ :returns dict: The serialized configuration.
305
+ """
306
+ result = self.to_project_config(with_packages=True)
307
+ result.update(self.to_profile_info(serialize_credentials=True))
308
+ result["cli_vars"] = deepcopy(self.cli_vars)
309
+ return result
310
+
311
+ def validate(self):
312
+ """Validate the configuration against its contract.
313
+
314
+ :raises DbtProjectError: If the configuration fails validation.
315
+ """
316
+ try:
317
+ Configuration.validate(self.serialize())
318
+ except ValidationError as e:
319
+ raise ConfigContractBrokenError(e) from e
320
+
321
+ # Called by RuntimeConfig.from_args
322
+ @classmethod
323
+ def collect_parts(cls: Type["RuntimeConfig"], args: Any) -> Tuple[Project, Profile]:
324
+ # profile_name from the project
325
+ project_root = args.project_dir if args.project_dir else os.getcwd()
326
+ cli_vars: Dict[str, Any] = getattr(args, "vars", {})
327
+ profile = cls.get_profile(
328
+ project_root,
329
+ cli_vars,
330
+ args,
331
+ )
332
+ flags = get_flags()
333
+ project = load_project(project_root, bool(flags.VERSION_CHECK), profile, cli_vars)
334
+ return project, profile
335
+
336
+ # Called in task/base.py, in BaseTask.from_args
337
+ @classmethod
338
+ def from_args(cls, args: Any) -> "RuntimeConfig":
339
+ """Given arguments, read in dbt_project.yml from the current directory,
340
+ read in packages.yml if it exists, and use them to find the profile to
341
+ load.
342
+
343
+ :param args: The arguments as parsed from the cli.
344
+ :raises DbtProjectError: If the project is invalid or missing.
345
+ :raises DbtProfileError: If the profile is invalid or missing.
346
+ :raises DbtValidationError: If the cli variables are invalid.
347
+ """
348
+ project, profile = cls.collect_parts(args)
349
+
350
+ return cls.from_parts(
351
+ project=project,
352
+ profile=profile,
353
+ args=args,
354
+ )
355
+
356
+ def get_metadata(self) -> ManifestMetadata:
357
+ return ManifestMetadata(
358
+ project_name=self.project_name,
359
+ project_id=self.hashed_name(),
360
+ user_id=tracking.active_user.id if tracking.active_user else None,
361
+ send_anonymous_usage_stats=(
362
+ get_flags().SEND_ANONYMOUS_USAGE_STATS if tracking.active_user else None
363
+ ),
364
+ adapter_type=self.credentials.type,
365
+ quoting=Quoting(
366
+ database=self.quoting.get("database", None),
367
+ schema=self.quoting.get("schema", None),
368
+ identifier=self.quoting.get("identifier", None),
369
+ column=self.quoting.get("column", None),
370
+ ),
371
+ run_started_at=(
372
+ tracking.active_user.run_started_at if tracking.active_user is not None else None
373
+ ),
374
+ )
375
+
376
+ def _get_v2_config_paths(
377
+ self,
378
+ config,
379
+ path: FQNPath,
380
+ paths: MutableSet[FQNPath],
381
+ ) -> PathSet:
382
+ for key, value in config.items():
383
+ if isinstance(value, dict) and not key.startswith("+"):
384
+ self._get_config_paths(value, path + (key,), paths)
385
+ else:
386
+ paths.add(path)
387
+ return frozenset(paths)
388
+
389
+ def _get_config_paths(
390
+ self,
391
+ config: Dict[str, Any],
392
+ path: FQNPath = (),
393
+ paths: Optional[MutableSet[FQNPath]] = None,
394
+ ) -> PathSet:
395
+ if paths is None:
396
+ paths = set()
397
+
398
+ for key, value in config.items():
399
+ if isinstance(value, dict) and not key.startswith("+"):
400
+ self._get_v2_config_paths(value, path + (key,), paths)
401
+ else:
402
+ paths.add(path)
403
+ return frozenset(paths)
404
+
405
+ def get_resource_config_paths(self) -> Dict[str, PathSet]:
406
+ """Return a dictionary with resource type keys whose values are
407
+ lists of lists of strings, where each inner list of strings represents
408
+ a configured path in the resource.
409
+ """
410
+ return {
411
+ "models": self._get_config_paths(self.models),
412
+ "seeds": self._get_config_paths(self.seeds),
413
+ "snapshots": self._get_config_paths(self.snapshots),
414
+ "sources": self._get_config_paths(self.sources),
415
+ "data_tests": self._get_config_paths(self.data_tests),
416
+ "unit_tests": self._get_config_paths(self.unit_tests),
417
+ "metrics": self._get_config_paths(self.metrics),
418
+ "semantic_models": self._get_config_paths(self.semantic_models),
419
+ "saved_queries": self._get_config_paths(self.saved_queries),
420
+ "exposures": self._get_config_paths(self.exposures),
421
+ "functions": self._get_config_paths(self.functions),
422
+ }
423
+
424
+ def warn_for_unused_resource_config_paths(
425
+ self,
426
+ resource_fqns: Mapping[str, PathSet],
427
+ disabled: PathSet,
428
+ ) -> None:
429
+ """Return a list of lists of strings, where each inner list of strings
430
+ represents a type + FQN path of a resource configuration that is not
431
+ used.
432
+ """
433
+ disabled_fqns = frozenset(tuple(fqn) for fqn in disabled)
434
+ resource_config_paths = self.get_resource_config_paths()
435
+ unused_resource_config_paths = []
436
+ for resource_type, config_paths in resource_config_paths.items():
437
+ used_fqns = resource_fqns.get(resource_type, frozenset())
438
+ fqns = used_fqns | disabled_fqns
439
+
440
+ for config_path in config_paths:
441
+ if not _is_config_used(config_path, fqns):
442
+ resource_path = ".".join(i for i in ((resource_type,) + config_path))
443
+ unused_resource_config_paths.append(resource_path)
444
+
445
+ if len(unused_resource_config_paths) == 0:
446
+ return
447
+
448
+ warn_or_error(UnusedResourceConfigPath(unused_config_paths=unused_resource_config_paths))
449
+
450
+ def load_dependencies(self, base_only=False) -> Mapping[str, "RuntimeConfig"]:
451
+ if self.dependencies is None:
452
+ all_projects = {self.project_name: self}
453
+ internal_packages = get_include_paths(self.credentials.type)
454
+ if base_only:
455
+ # Test setup -- we want to load macros without dependencies
456
+ project_paths = itertools.chain(internal_packages)
457
+ else:
458
+ # raise exception if fewer installed packages than in packages.yml
459
+ count_packages_specified = len(self.packages.packages) # type: ignore
460
+ count_packages_installed = len(tuple(self._get_project_directories()))
461
+ if count_packages_specified > count_packages_installed:
462
+ raise UninstalledPackagesFoundError(
463
+ count_packages_specified,
464
+ count_packages_installed,
465
+ self.packages_specified_path,
466
+ self.packages_install_path,
467
+ )
468
+ project_paths = itertools.chain(internal_packages, self._get_project_directories())
469
+ for project_name, project in self.load_projects(project_paths):
470
+ if project_name in all_projects:
471
+ raise NonUniquePackageNameError(project_name)
472
+ all_projects[project_name] = project
473
+ self.dependencies = all_projects
474
+ return self.dependencies
475
+
476
+ def clear_dependencies(self):
477
+ self.dependencies = None
478
+
479
+ # Called by 'load_dependencies' in this class
480
+ def load_projects(self, paths: Iterable[Path]) -> Iterator[Tuple[str, "RuntimeConfig"]]:
481
+ for path in paths:
482
+ try:
483
+ project = self.new_project(str(path))
484
+ except DbtProjectError as e:
485
+ raise DbtProjectError(
486
+ f"Failed to read package: {e}",
487
+ result_type="invalid_project",
488
+ path=path,
489
+ ) from e
490
+ else:
491
+ yield project.project_name, project
492
+
493
+ def _get_project_directories(self) -> Iterator[Path]:
494
+ root = Path(self.project_root) / self.packages_install_path
495
+
496
+ if root.exists():
497
+ for path in root.iterdir():
498
+ if path.is_dir() and not path.name.startswith("__"):
499
+ yield path
500
+
501
+
502
+ class UnsetCredentials(Credentials):
503
+ def __init__(self) -> None:
504
+ super().__init__("", "")
505
+
506
+ @property
507
+ def type(self):
508
+ return None
509
+
510
+ @property
511
+ def unique_field(self):
512
+ return None
513
+
514
+ def connection_info(self, *args, **kwargs):
515
+ return {}
516
+
517
+ def _connection_keys(self):
518
+ return ()
519
+
520
+
521
+ # This is used by commands which do not require
522
+ # a profile, i.e. dbt deps and clean
523
+ class UnsetProfile(Profile):
524
+ def __init__(self):
525
+ self.credentials = UnsetCredentials()
526
+ self.profile_name = ""
527
+ self.target_name = ""
528
+ self.threads = -1
529
+
530
+ def to_target_dict(self):
531
+ return DictDefaultEmptyStr({})
532
+
533
+ def __getattribute__(self, name):
534
+ if name in {"profile_name", "target_name", "threads"}:
535
+ raise DbtRuntimeError(f'Error: disallowed attribute "{name}" - no profile!')
536
+
537
+ return Profile.__getattribute__(self, name)
538
+
539
+
540
+ UNUSED_RESOURCE_CONFIGURATION_PATH_MESSAGE = """\
541
+ Configuration paths exist in your dbt_project.yml file which do not \
542
+ apply to any resources.
543
+ There are {} unused configuration paths:
544
+ {}
545
+ """
546
+
547
+
548
+ def _is_config_used(path, fqns):
549
+ if fqns:
550
+ for fqn in fqns:
551
+ if len(path) <= len(fqn) and fqn[: len(path)] == path:
552
+ return True
553
+ return False