dvt-core 0.52.2__cp310-cp310-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.
Potentially problematic release.
This version of dvt-core might be problematic. Click here for more details.
- dbt/__init__.py +7 -0
- dbt/_pydantic_shim.py +26 -0
- dbt/artifacts/__init__.py +0 -0
- dbt/artifacts/exceptions/__init__.py +1 -0
- dbt/artifacts/exceptions/schemas.py +31 -0
- dbt/artifacts/resources/__init__.py +116 -0
- dbt/artifacts/resources/base.py +67 -0
- dbt/artifacts/resources/types.py +93 -0
- dbt/artifacts/resources/v1/analysis.py +10 -0
- dbt/artifacts/resources/v1/catalog.py +23 -0
- dbt/artifacts/resources/v1/components.py +274 -0
- dbt/artifacts/resources/v1/config.py +277 -0
- dbt/artifacts/resources/v1/documentation.py +11 -0
- dbt/artifacts/resources/v1/exposure.py +51 -0
- dbt/artifacts/resources/v1/function.py +52 -0
- dbt/artifacts/resources/v1/generic_test.py +31 -0
- dbt/artifacts/resources/v1/group.py +21 -0
- dbt/artifacts/resources/v1/hook.py +11 -0
- dbt/artifacts/resources/v1/macro.py +29 -0
- dbt/artifacts/resources/v1/metric.py +172 -0
- dbt/artifacts/resources/v1/model.py +145 -0
- dbt/artifacts/resources/v1/owner.py +10 -0
- dbt/artifacts/resources/v1/saved_query.py +111 -0
- dbt/artifacts/resources/v1/seed.py +41 -0
- dbt/artifacts/resources/v1/semantic_layer_components.py +72 -0
- dbt/artifacts/resources/v1/semantic_model.py +314 -0
- dbt/artifacts/resources/v1/singular_test.py +14 -0
- dbt/artifacts/resources/v1/snapshot.py +91 -0
- dbt/artifacts/resources/v1/source_definition.py +84 -0
- dbt/artifacts/resources/v1/sql_operation.py +10 -0
- dbt/artifacts/resources/v1/unit_test_definition.py +77 -0
- dbt/artifacts/schemas/__init__.py +0 -0
- dbt/artifacts/schemas/base.py +191 -0
- dbt/artifacts/schemas/batch_results.py +24 -0
- dbt/artifacts/schemas/catalog/__init__.py +11 -0
- dbt/artifacts/schemas/catalog/v1/__init__.py +0 -0
- dbt/artifacts/schemas/catalog/v1/catalog.py +59 -0
- dbt/artifacts/schemas/freshness/__init__.py +1 -0
- dbt/artifacts/schemas/freshness/v3/__init__.py +0 -0
- dbt/artifacts/schemas/freshness/v3/freshness.py +158 -0
- dbt/artifacts/schemas/manifest/__init__.py +2 -0
- dbt/artifacts/schemas/manifest/v12/__init__.py +0 -0
- dbt/artifacts/schemas/manifest/v12/manifest.py +211 -0
- dbt/artifacts/schemas/results.py +147 -0
- dbt/artifacts/schemas/run/__init__.py +2 -0
- dbt/artifacts/schemas/run/v5/__init__.py +0 -0
- dbt/artifacts/schemas/run/v5/run.py +184 -0
- dbt/artifacts/schemas/upgrades/__init__.py +4 -0
- dbt/artifacts/schemas/upgrades/upgrade_manifest.py +174 -0
- dbt/artifacts/schemas/upgrades/upgrade_manifest_dbt_version.py +2 -0
- dbt/artifacts/utils/validation.py +153 -0
- dbt/cli/__init__.py +1 -0
- dbt/cli/context.py +17 -0
- dbt/cli/exceptions.py +57 -0
- dbt/cli/flags.py +560 -0
- dbt/cli/main.py +2039 -0
- dbt/cli/option_types.py +121 -0
- dbt/cli/options.py +80 -0
- dbt/cli/params.py +804 -0
- dbt/cli/requires.py +490 -0
- dbt/cli/resolvers.py +50 -0
- dbt/cli/types.py +40 -0
- dbt/clients/__init__.py +0 -0
- dbt/clients/checked_load.py +83 -0
- dbt/clients/git.py +164 -0
- dbt/clients/jinja.py +206 -0
- dbt/clients/jinja_static.py +245 -0
- dbt/clients/registry.py +192 -0
- dbt/clients/yaml_helper.py +68 -0
- dbt/compilation.py +876 -0
- dbt/compute/__init__.py +14 -0
- dbt/compute/engines/__init__.py +12 -0
- dbt/compute/engines/spark_engine.py +624 -0
- dbt/compute/federated_executor.py +837 -0
- dbt/compute/filter_pushdown.cpython-310-darwin.so +0 -0
- dbt/compute/filter_pushdown.py +273 -0
- dbt/compute/jar_provisioning.cpython-310-darwin.so +0 -0
- dbt/compute/jar_provisioning.py +255 -0
- dbt/compute/java_compat.cpython-310-darwin.so +0 -0
- dbt/compute/java_compat.py +689 -0
- dbt/compute/jdbc_utils.cpython-310-darwin.so +0 -0
- dbt/compute/jdbc_utils.py +678 -0
- dbt/compute/smart_selector.cpython-310-darwin.so +0 -0
- dbt/compute/smart_selector.py +311 -0
- dbt/compute/strategies/__init__.py +54 -0
- dbt/compute/strategies/base.py +165 -0
- dbt/compute/strategies/dataproc.py +207 -0
- dbt/compute/strategies/emr.py +203 -0
- dbt/compute/strategies/local.py +364 -0
- dbt/compute/strategies/standalone.py +262 -0
- dbt/config/__init__.py +4 -0
- dbt/config/catalogs.py +94 -0
- dbt/config/compute.cpython-310-darwin.so +0 -0
- dbt/config/compute.py +547 -0
- dbt/config/dvt_profile.cpython-310-darwin.so +0 -0
- dbt/config/dvt_profile.py +342 -0
- dbt/config/profile.py +422 -0
- dbt/config/project.py +873 -0
- dbt/config/project_utils.py +28 -0
- dbt/config/renderer.py +231 -0
- dbt/config/runtime.py +553 -0
- dbt/config/selectors.py +208 -0
- dbt/config/utils.py +77 -0
- dbt/constants.py +28 -0
- dbt/context/__init__.py +0 -0
- dbt/context/base.py +745 -0
- dbt/context/configured.py +135 -0
- dbt/context/context_config.py +382 -0
- dbt/context/docs.py +82 -0
- dbt/context/exceptions_jinja.py +178 -0
- dbt/context/macro_resolver.py +195 -0
- dbt/context/macros.py +171 -0
- dbt/context/manifest.py +72 -0
- dbt/context/providers.py +2249 -0
- dbt/context/query_header.py +13 -0
- dbt/context/secret.py +58 -0
- dbt/context/target.py +74 -0
- dbt/contracts/__init__.py +0 -0
- dbt/contracts/files.py +413 -0
- dbt/contracts/graph/__init__.py +0 -0
- dbt/contracts/graph/manifest.py +1904 -0
- dbt/contracts/graph/metrics.py +97 -0
- dbt/contracts/graph/model_config.py +70 -0
- dbt/contracts/graph/node_args.py +42 -0
- dbt/contracts/graph/nodes.py +1806 -0
- dbt/contracts/graph/semantic_manifest.py +232 -0
- dbt/contracts/graph/unparsed.py +811 -0
- dbt/contracts/project.py +417 -0
- dbt/contracts/results.py +53 -0
- dbt/contracts/selection.py +23 -0
- dbt/contracts/sql.py +85 -0
- dbt/contracts/state.py +68 -0
- dbt/contracts/util.py +46 -0
- dbt/deprecations.py +346 -0
- dbt/deps/__init__.py +0 -0
- dbt/deps/base.py +152 -0
- dbt/deps/git.py +195 -0
- dbt/deps/local.py +79 -0
- dbt/deps/registry.py +130 -0
- dbt/deps/resolver.py +149 -0
- dbt/deps/tarball.py +120 -0
- dbt/docs/source/_ext/dbt_click.py +119 -0
- dbt/docs/source/conf.py +32 -0
- dbt/env_vars.py +64 -0
- dbt/event_time/event_time.py +40 -0
- dbt/event_time/sample_window.py +60 -0
- dbt/events/__init__.py +15 -0
- dbt/events/base_types.py +36 -0
- dbt/events/core_types_pb2.py +2 -0
- dbt/events/logging.py +108 -0
- dbt/events/types.py +2516 -0
- dbt/exceptions.py +1486 -0
- dbt/flags.py +89 -0
- dbt/graph/__init__.py +11 -0
- dbt/graph/cli.py +247 -0
- dbt/graph/graph.py +172 -0
- dbt/graph/queue.py +214 -0
- dbt/graph/selector.py +374 -0
- dbt/graph/selector_methods.py +975 -0
- dbt/graph/selector_spec.py +222 -0
- dbt/graph/thread_pool.py +18 -0
- dbt/hooks.py +21 -0
- dbt/include/README.md +49 -0
- dbt/include/__init__.py +3 -0
- dbt/include/starter_project/.gitignore +4 -0
- dbt/include/starter_project/README.md +15 -0
- dbt/include/starter_project/__init__.py +3 -0
- dbt/include/starter_project/analyses/.gitkeep +0 -0
- dbt/include/starter_project/dbt_project.yml +36 -0
- dbt/include/starter_project/macros/.gitkeep +0 -0
- dbt/include/starter_project/models/example/my_first_dbt_model.sql +27 -0
- dbt/include/starter_project/models/example/my_second_dbt_model.sql +6 -0
- dbt/include/starter_project/models/example/schema.yml +21 -0
- dbt/include/starter_project/seeds/.gitkeep +0 -0
- dbt/include/starter_project/snapshots/.gitkeep +0 -0
- dbt/include/starter_project/tests/.gitkeep +0 -0
- dbt/internal_deprecations.py +26 -0
- dbt/jsonschemas/__init__.py +3 -0
- dbt/jsonschemas/jsonschemas.py +309 -0
- dbt/jsonschemas/project/0.0.110.json +4717 -0
- dbt/jsonschemas/project/0.0.85.json +2015 -0
- dbt/jsonschemas/resources/0.0.110.json +2636 -0
- dbt/jsonschemas/resources/0.0.85.json +2536 -0
- dbt/jsonschemas/resources/latest.json +6773 -0
- dbt/links.py +4 -0
- dbt/materializations/__init__.py +0 -0
- dbt/materializations/incremental/__init__.py +0 -0
- dbt/materializations/incremental/microbatch.py +236 -0
- dbt/mp_context.py +8 -0
- dbt/node_types.py +37 -0
- dbt/parser/__init__.py +23 -0
- dbt/parser/analysis.py +21 -0
- dbt/parser/base.py +548 -0
- dbt/parser/common.py +266 -0
- dbt/parser/docs.py +52 -0
- dbt/parser/fixtures.py +51 -0
- dbt/parser/functions.py +30 -0
- dbt/parser/generic_test.py +100 -0
- dbt/parser/generic_test_builders.py +333 -0
- dbt/parser/hooks.py +118 -0
- dbt/parser/macros.py +137 -0
- dbt/parser/manifest.py +2204 -0
- dbt/parser/models.py +573 -0
- dbt/parser/partial.py +1178 -0
- dbt/parser/read_files.py +445 -0
- dbt/parser/schema_generic_tests.py +422 -0
- dbt/parser/schema_renderer.py +111 -0
- dbt/parser/schema_yaml_readers.py +935 -0
- dbt/parser/schemas.py +1466 -0
- dbt/parser/search.py +149 -0
- dbt/parser/seeds.py +28 -0
- dbt/parser/singular_test.py +20 -0
- dbt/parser/snapshots.py +44 -0
- dbt/parser/sources.py +558 -0
- dbt/parser/sql.py +62 -0
- dbt/parser/unit_tests.py +621 -0
- dbt/plugins/__init__.py +20 -0
- dbt/plugins/contracts.py +9 -0
- dbt/plugins/exceptions.py +2 -0
- dbt/plugins/manager.py +163 -0
- dbt/plugins/manifest.py +21 -0
- dbt/profiler.py +20 -0
- dbt/py.typed +1 -0
- dbt/query_analyzer.cpython-310-darwin.so +0 -0
- dbt/query_analyzer.py +410 -0
- dbt/runners/__init__.py +2 -0
- dbt/runners/exposure_runner.py +7 -0
- dbt/runners/no_op_runner.py +45 -0
- dbt/runners/saved_query_runner.py +7 -0
- dbt/selected_resources.py +8 -0
- dbt/task/__init__.py +0 -0
- dbt/task/base.py +503 -0
- dbt/task/build.py +197 -0
- dbt/task/clean.py +56 -0
- dbt/task/clone.py +161 -0
- dbt/task/compile.py +150 -0
- dbt/task/compute.py +454 -0
- dbt/task/debug.py +505 -0
- dbt/task/deps.py +280 -0
- dbt/task/docs/__init__.py +3 -0
- dbt/task/docs/generate.py +660 -0
- dbt/task/docs/index.html +250 -0
- dbt/task/docs/serve.py +29 -0
- dbt/task/freshness.py +322 -0
- dbt/task/function.py +121 -0
- dbt/task/group_lookup.py +46 -0
- dbt/task/init.py +553 -0
- dbt/task/java.py +316 -0
- dbt/task/list.py +236 -0
- dbt/task/printer.py +175 -0
- dbt/task/retry.py +175 -0
- dbt/task/run.py +1306 -0
- dbt/task/run_operation.py +141 -0
- dbt/task/runnable.py +758 -0
- dbt/task/seed.py +103 -0
- dbt/task/show.py +149 -0
- dbt/task/snapshot.py +56 -0
- dbt/task/spark.py +414 -0
- dbt/task/sql.py +110 -0
- dbt/task/target_sync.py +759 -0
- dbt/task/test.py +464 -0
- dbt/tests/fixtures/__init__.py +1 -0
- dbt/tests/fixtures/project.py +620 -0
- dbt/tests/util.py +651 -0
- dbt/tracking.py +529 -0
- dbt/utils/__init__.py +3 -0
- dbt/utils/artifact_upload.py +151 -0
- dbt/utils/utils.py +408 -0
- dbt/version.py +268 -0
- dvt_cli/__init__.py +72 -0
- dvt_core-0.52.2.dist-info/METADATA +286 -0
- dvt_core-0.52.2.dist-info/RECORD +275 -0
- dvt_core-0.52.2.dist-info/WHEEL +5 -0
- dvt_core-0.52.2.dist-info/entry_points.txt +2 -0
- dvt_core-0.52.2.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
"""
|
|
2
|
+
DVT (Data Virtualization Tool) Profile Extensions
|
|
3
|
+
|
|
4
|
+
This module extends the dbt Profile class to support multiple named connections
|
|
5
|
+
per profile, enabling multi-source data federation.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
from dataclasses import dataclass, field
|
|
10
|
+
from typing import Any, Dict, Optional, Tuple
|
|
11
|
+
|
|
12
|
+
from dbt.adapters.contracts.connection import Credentials
|
|
13
|
+
from dbt.config.profile import Profile
|
|
14
|
+
from dbt.exceptions import DbtProfileError, DbtRuntimeError
|
|
15
|
+
from dbt_common.dataclass_schema import ValidationError
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass
|
|
19
|
+
class DVTProfile(Profile):
|
|
20
|
+
"""
|
|
21
|
+
Extended Profile class that supports multiple named connections.
|
|
22
|
+
|
|
23
|
+
In addition to the standard dbt Profile fields (profile_name, target_name, threads, credentials),
|
|
24
|
+
DVTProfile adds:
|
|
25
|
+
- connections: Dict of named connections (each with its own Credentials)
|
|
26
|
+
- default_target: The connection name to use for materialization by default
|
|
27
|
+
|
|
28
|
+
The 'credentials' field is maintained for backward compatibility and points to the default_target credentials.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
# Additional DVT-specific fields
|
|
32
|
+
outputs: Dict[str, Credentials] = field(default_factory=dict)
|
|
33
|
+
default_target: Optional[str] = None
|
|
34
|
+
|
|
35
|
+
def __init__(
|
|
36
|
+
self,
|
|
37
|
+
profile_name: str,
|
|
38
|
+
target_name: str,
|
|
39
|
+
threads: int,
|
|
40
|
+
credentials: Credentials,
|
|
41
|
+
connections: Optional[Dict[str, Credentials]] = None,
|
|
42
|
+
default_target: Optional[str] = None,
|
|
43
|
+
) -> None:
|
|
44
|
+
"""
|
|
45
|
+
Initialize DVT Profile with multi-connection support.
|
|
46
|
+
|
|
47
|
+
:param profile_name: Name of the profile
|
|
48
|
+
:param target_name: Name of the target (for backward compatibility)
|
|
49
|
+
:param threads: Number of threads for parallel execution
|
|
50
|
+
:param credentials: Default credentials (for backward compatibility)
|
|
51
|
+
:param connections: Dictionary of named outputs (same as dbt)
|
|
52
|
+
:param default_target: Default output name for materialization
|
|
53
|
+
"""
|
|
54
|
+
super().__init__(
|
|
55
|
+
profile_name=profile_name,
|
|
56
|
+
target_name=target_name,
|
|
57
|
+
threads=threads,
|
|
58
|
+
credentials=credentials,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
self.outputs = connections or {}
|
|
62
|
+
self.default_target = default_target
|
|
63
|
+
|
|
64
|
+
# If outputs dict is provided but default_target is not, use target_name
|
|
65
|
+
if self.outputs and not self.default_target:
|
|
66
|
+
self.default_target = target_name
|
|
67
|
+
|
|
68
|
+
# Ensure backward compatibility: if outputs is empty, populate with single credentials
|
|
69
|
+
if not self.outputs and credentials:
|
|
70
|
+
self.outputs[target_name] = credentials
|
|
71
|
+
self.default_target = target_name
|
|
72
|
+
|
|
73
|
+
def get_connection(self, connection_name: Optional[str] = None) -> Credentials:
|
|
74
|
+
"""
|
|
75
|
+
Get credentials for a specific output.
|
|
76
|
+
|
|
77
|
+
:param connection_name: Name of the output. If None, returns default_target credentials.
|
|
78
|
+
:returns: Credentials for the specified output
|
|
79
|
+
:raises DbtProfileError: If connection_name not found
|
|
80
|
+
"""
|
|
81
|
+
name = connection_name or self.default_target
|
|
82
|
+
|
|
83
|
+
if not name:
|
|
84
|
+
raise DbtProfileError("No output name specified and no default_target configured")
|
|
85
|
+
|
|
86
|
+
if name not in self.outputs:
|
|
87
|
+
available = ", ".join(self.outputs.keys())
|
|
88
|
+
raise DbtProfileError(
|
|
89
|
+
f"Output '{name}' not found in profile '{self.profile_name}'. "
|
|
90
|
+
f"Available outputs: {available}"
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
return self.outputs[name]
|
|
94
|
+
|
|
95
|
+
def to_profile_info(self, serialize_credentials: bool = False) -> Dict[str, Any]:
|
|
96
|
+
"""
|
|
97
|
+
Serialize DVT profile to dict.
|
|
98
|
+
|
|
99
|
+
:param serialize_credentials: If True, serialize all credentials to dicts
|
|
100
|
+
:returns: Serialized profile dict
|
|
101
|
+
"""
|
|
102
|
+
result = super().to_profile_info(serialize_credentials=serialize_credentials)
|
|
103
|
+
|
|
104
|
+
# DVT uses standard dbt format - no need to serialize outputs separately
|
|
105
|
+
# since multi-output support is just for convenience, validation uses single target
|
|
106
|
+
|
|
107
|
+
return result
|
|
108
|
+
|
|
109
|
+
@staticmethod
|
|
110
|
+
def _parse_connections_from_profile(
|
|
111
|
+
profile: Dict[str, Any], profile_name: str
|
|
112
|
+
) -> Tuple[Dict[str, Credentials], Optional[str]]:
|
|
113
|
+
"""
|
|
114
|
+
Parse multiple outputs from profile configuration.
|
|
115
|
+
|
|
116
|
+
DVT uses standard dbt format with 'outputs' key and optional multi-output support:
|
|
117
|
+
outputs:
|
|
118
|
+
postgres_prod:
|
|
119
|
+
type: postgres
|
|
120
|
+
host: prod.example.com
|
|
121
|
+
...
|
|
122
|
+
snowflake_warehouse:
|
|
123
|
+
type: snowflake
|
|
124
|
+
account: abc123
|
|
125
|
+
...
|
|
126
|
+
target: postgres_prod
|
|
127
|
+
|
|
128
|
+
:param profile: Raw profile dict from YAML
|
|
129
|
+
:param profile_name: Name of the profile
|
|
130
|
+
:returns: Tuple of (outputs dict, default_target name)
|
|
131
|
+
:raises DbtProfileError: If profile format is invalid
|
|
132
|
+
"""
|
|
133
|
+
# avoid an import cycle
|
|
134
|
+
from dbt.adapters.factory import load_plugin
|
|
135
|
+
|
|
136
|
+
outputs = {}
|
|
137
|
+
default_target = None
|
|
138
|
+
|
|
139
|
+
# Check for 'outputs' key (standard dbt format)
|
|
140
|
+
if "outputs" in profile:
|
|
141
|
+
raw_outputs = profile["outputs"]
|
|
142
|
+
|
|
143
|
+
if not isinstance(raw_outputs, dict):
|
|
144
|
+
raise DbtProfileError(
|
|
145
|
+
f"'outputs' in profile '{profile_name}' must be a dictionary"
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
# Parse each output
|
|
149
|
+
for output_name, output_data in raw_outputs.items():
|
|
150
|
+
if not isinstance(output_data, dict):
|
|
151
|
+
raise DbtProfileError(
|
|
152
|
+
f"Output '{output_name}' in profile '{profile_name}' must be a dictionary"
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
if "type" not in output_data:
|
|
156
|
+
raise DbtProfileError(
|
|
157
|
+
f"Output '{output_name}' in profile '{profile_name}' missing required 'type' field"
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
# Parse credentials for this output
|
|
161
|
+
output_data_copy = output_data.copy()
|
|
162
|
+
typename = output_data_copy.pop("type")
|
|
163
|
+
|
|
164
|
+
try:
|
|
165
|
+
cls = load_plugin(typename)
|
|
166
|
+
data = cls.translate_aliases(output_data_copy)
|
|
167
|
+
cls.validate(data)
|
|
168
|
+
credentials = cls.from_dict(data)
|
|
169
|
+
outputs[output_name] = credentials
|
|
170
|
+
except (DbtRuntimeError, ValidationError) as e:
|
|
171
|
+
msg = str(e) if isinstance(e, DbtRuntimeError) else e.message
|
|
172
|
+
raise DbtProfileError(
|
|
173
|
+
f"Credentials for output '{output_name}' in profile '{profile_name}' invalid: {msg}"
|
|
174
|
+
) from e
|
|
175
|
+
|
|
176
|
+
# Get default target - use 'target' field (standard dbt)
|
|
177
|
+
# Also support 'default_target' for backward compatibility
|
|
178
|
+
default_target = profile.get("target") or profile.get("default_target")
|
|
179
|
+
if not default_target and outputs:
|
|
180
|
+
# If not specified, use first output as default
|
|
181
|
+
default_target = list(outputs.keys())[0]
|
|
182
|
+
|
|
183
|
+
if default_target and default_target not in outputs:
|
|
184
|
+
raise DbtProfileError(
|
|
185
|
+
f"target '{default_target}' not found in outputs of profile '{profile_name}'"
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
return outputs, default_target
|
|
189
|
+
|
|
190
|
+
@classmethod
|
|
191
|
+
def from_raw_profile_info(
|
|
192
|
+
cls,
|
|
193
|
+
raw_profile: Dict[str, Any],
|
|
194
|
+
profile_name: str,
|
|
195
|
+
renderer: Any, # ProfileRenderer
|
|
196
|
+
target_override: Optional[str] = None,
|
|
197
|
+
threads_override: Optional[int] = None,
|
|
198
|
+
) -> "DVTProfile":
|
|
199
|
+
"""
|
|
200
|
+
Create a DVTProfile from raw profile information.
|
|
201
|
+
|
|
202
|
+
This method supports both DVT multi-connection format and legacy dbt format.
|
|
203
|
+
|
|
204
|
+
:param raw_profile: The profile data for a single profile
|
|
205
|
+
:param profile_name: The profile name used
|
|
206
|
+
:param renderer: The config renderer
|
|
207
|
+
:param target_override: The target to use, if provided on the command line
|
|
208
|
+
:param threads_override: The thread count to use, if provided
|
|
209
|
+
:returns: The new DVTProfile object
|
|
210
|
+
:raises DbtProfileError: If the profile is invalid
|
|
211
|
+
"""
|
|
212
|
+
# Check if this is a DVT multi-output profile
|
|
213
|
+
if "outputs" in raw_profile and len(raw_profile.get("outputs", {})) > 0:
|
|
214
|
+
# Parse outputs
|
|
215
|
+
outputs, default_target = cls._parse_connections_from_profile(
|
|
216
|
+
raw_profile, profile_name
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
if not outputs:
|
|
220
|
+
raise DbtProfileError(
|
|
221
|
+
f"Profile '{profile_name}' has 'outputs' key but no valid outputs defined"
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
# Get threads
|
|
225
|
+
threads = raw_profile.get("threads", 1)
|
|
226
|
+
if threads_override is not None:
|
|
227
|
+
threads = threads_override
|
|
228
|
+
|
|
229
|
+
# Determine target name
|
|
230
|
+
if target_override:
|
|
231
|
+
target_name = target_override
|
|
232
|
+
if target_name not in outputs:
|
|
233
|
+
raise DbtProfileError(
|
|
234
|
+
f"Target override '{target_name}' not found in outputs of profile '{profile_name}'"
|
|
235
|
+
)
|
|
236
|
+
default_target = target_name
|
|
237
|
+
else:
|
|
238
|
+
target_name = default_target or list(outputs.keys())[0]
|
|
239
|
+
|
|
240
|
+
# Get default credentials for backward compatibility
|
|
241
|
+
credentials = outputs[target_name]
|
|
242
|
+
|
|
243
|
+
profile = cls(
|
|
244
|
+
profile_name=profile_name,
|
|
245
|
+
target_name=target_name,
|
|
246
|
+
threads=threads,
|
|
247
|
+
credentials=credentials,
|
|
248
|
+
connections=outputs,
|
|
249
|
+
default_target=default_target,
|
|
250
|
+
)
|
|
251
|
+
profile.validate()
|
|
252
|
+
return profile
|
|
253
|
+
|
|
254
|
+
else:
|
|
255
|
+
# Fall back to legacy dbt format - use parent class implementation
|
|
256
|
+
legacy_profile = Profile.from_raw_profile_info(
|
|
257
|
+
raw_profile=raw_profile,
|
|
258
|
+
profile_name=profile_name,
|
|
259
|
+
renderer=renderer,
|
|
260
|
+
target_override=target_override,
|
|
261
|
+
threads_override=threads_override,
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
# Convert to DVTProfile for consistency
|
|
265
|
+
return cls(
|
|
266
|
+
profile_name=legacy_profile.profile_name,
|
|
267
|
+
target_name=legacy_profile.target_name,
|
|
268
|
+
threads=legacy_profile.threads,
|
|
269
|
+
credentials=legacy_profile.credentials,
|
|
270
|
+
connections={legacy_profile.target_name: legacy_profile.credentials},
|
|
271
|
+
default_target=legacy_profile.target_name,
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
@classmethod
|
|
275
|
+
def from_raw_profiles(
|
|
276
|
+
cls,
|
|
277
|
+
raw_profiles: Dict[str, Any],
|
|
278
|
+
profile_name: str,
|
|
279
|
+
renderer: Any, # ProfileRenderer
|
|
280
|
+
target_override: Optional[str] = None,
|
|
281
|
+
threads_override: Optional[int] = None,
|
|
282
|
+
) -> "DVTProfile":
|
|
283
|
+
"""
|
|
284
|
+
Create DVTProfile from raw profiles dict.
|
|
285
|
+
|
|
286
|
+
:param raw_profiles: The profile data, from disk as yaml
|
|
287
|
+
:param profile_name: The profile name to use
|
|
288
|
+
:param renderer: The config renderer
|
|
289
|
+
:param target_override: The target to use, if provided
|
|
290
|
+
:param threads_override: The thread count to use, if provided
|
|
291
|
+
:returns: The new DVTProfile object
|
|
292
|
+
"""
|
|
293
|
+
from dbt.exceptions import DbtProjectError
|
|
294
|
+
|
|
295
|
+
if profile_name not in raw_profiles:
|
|
296
|
+
raise DbtProjectError(f"Could not find profile named '{profile_name}'")
|
|
297
|
+
|
|
298
|
+
raw_profile = raw_profiles[profile_name]
|
|
299
|
+
if not raw_profile:
|
|
300
|
+
raise DbtProfileError(f"Profile {profile_name} in profiles.yml is empty")
|
|
301
|
+
|
|
302
|
+
return cls.from_raw_profile_info(
|
|
303
|
+
raw_profile=raw_profile,
|
|
304
|
+
profile_name=profile_name,
|
|
305
|
+
renderer=renderer,
|
|
306
|
+
target_override=target_override,
|
|
307
|
+
threads_override=threads_override,
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
@classmethod
|
|
311
|
+
def render(
|
|
312
|
+
cls,
|
|
313
|
+
renderer: Any, # ProfileRenderer
|
|
314
|
+
project_profile_name: Optional[str],
|
|
315
|
+
profile_name_override: Optional[str] = None,
|
|
316
|
+
target_override: Optional[str] = None,
|
|
317
|
+
threads_override: Optional[int] = None,
|
|
318
|
+
) -> "DVTProfile":
|
|
319
|
+
"""
|
|
320
|
+
Render a DVTProfile from disk.
|
|
321
|
+
|
|
322
|
+
:param renderer: The config renderer
|
|
323
|
+
:param project_profile_name: The profile name from project
|
|
324
|
+
:param profile_name_override: Profile name override from CLI
|
|
325
|
+
:param target_override: Target override from CLI
|
|
326
|
+
:param threads_override: Threads override from CLI
|
|
327
|
+
:returns: The new DVTProfile object
|
|
328
|
+
"""
|
|
329
|
+
from dbt.config.profile import read_profile
|
|
330
|
+
from dbt.flags import get_flags
|
|
331
|
+
|
|
332
|
+
flags = get_flags()
|
|
333
|
+
raw_profiles = read_profile(flags.PROFILES_DIR)
|
|
334
|
+
profile_name = cls.pick_profile_name(profile_name_override, project_profile_name)
|
|
335
|
+
|
|
336
|
+
return cls.from_raw_profiles(
|
|
337
|
+
raw_profiles=raw_profiles,
|
|
338
|
+
profile_name=profile_name,
|
|
339
|
+
renderer=renderer,
|
|
340
|
+
target_override=target_override,
|
|
341
|
+
threads_override=threads_override,
|
|
342
|
+
)
|