dvt-core 1.11.0b4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of dvt-core might be problematic. Click here for more details.
- dvt/__init__.py +7 -0
- dvt/_pydantic_shim.py +26 -0
- dvt/adapters/__init__.py +16 -0
- dvt/adapters/multi_adapter_manager.py +268 -0
- dvt/artifacts/__init__.py +0 -0
- dvt/artifacts/exceptions/__init__.py +1 -0
- dvt/artifacts/exceptions/schemas.py +31 -0
- dvt/artifacts/resources/__init__.py +116 -0
- dvt/artifacts/resources/base.py +68 -0
- dvt/artifacts/resources/types.py +93 -0
- dvt/artifacts/resources/v1/analysis.py +10 -0
- dvt/artifacts/resources/v1/catalog.py +23 -0
- dvt/artifacts/resources/v1/components.py +275 -0
- dvt/artifacts/resources/v1/config.py +282 -0
- dvt/artifacts/resources/v1/documentation.py +11 -0
- dvt/artifacts/resources/v1/exposure.py +52 -0
- dvt/artifacts/resources/v1/function.py +53 -0
- dvt/artifacts/resources/v1/generic_test.py +32 -0
- dvt/artifacts/resources/v1/group.py +22 -0
- dvt/artifacts/resources/v1/hook.py +11 -0
- dvt/artifacts/resources/v1/macro.py +30 -0
- dvt/artifacts/resources/v1/metric.py +173 -0
- dvt/artifacts/resources/v1/model.py +146 -0
- dvt/artifacts/resources/v1/owner.py +10 -0
- dvt/artifacts/resources/v1/saved_query.py +112 -0
- dvt/artifacts/resources/v1/seed.py +42 -0
- dvt/artifacts/resources/v1/semantic_layer_components.py +72 -0
- dvt/artifacts/resources/v1/semantic_model.py +315 -0
- dvt/artifacts/resources/v1/singular_test.py +14 -0
- dvt/artifacts/resources/v1/snapshot.py +92 -0
- dvt/artifacts/resources/v1/source_definition.py +85 -0
- dvt/artifacts/resources/v1/sql_operation.py +10 -0
- dvt/artifacts/resources/v1/unit_test_definition.py +78 -0
- dvt/artifacts/schemas/__init__.py +0 -0
- dvt/artifacts/schemas/base.py +191 -0
- dvt/artifacts/schemas/batch_results.py +24 -0
- dvt/artifacts/schemas/catalog/__init__.py +12 -0
- dvt/artifacts/schemas/catalog/v1/__init__.py +0 -0
- dvt/artifacts/schemas/catalog/v1/catalog.py +60 -0
- dvt/artifacts/schemas/freshness/__init__.py +1 -0
- dvt/artifacts/schemas/freshness/v3/__init__.py +0 -0
- dvt/artifacts/schemas/freshness/v3/freshness.py +159 -0
- dvt/artifacts/schemas/manifest/__init__.py +2 -0
- dvt/artifacts/schemas/manifest/v12/__init__.py +0 -0
- dvt/artifacts/schemas/manifest/v12/manifest.py +212 -0
- dvt/artifacts/schemas/results.py +148 -0
- dvt/artifacts/schemas/run/__init__.py +2 -0
- dvt/artifacts/schemas/run/v5/__init__.py +0 -0
- dvt/artifacts/schemas/run/v5/run.py +184 -0
- dvt/artifacts/schemas/upgrades/__init__.py +4 -0
- dvt/artifacts/schemas/upgrades/upgrade_manifest.py +174 -0
- dvt/artifacts/schemas/upgrades/upgrade_manifest_dbt_version.py +2 -0
- dvt/artifacts/utils/validation.py +153 -0
- dvt/cli/__init__.py +1 -0
- dvt/cli/context.py +16 -0
- dvt/cli/exceptions.py +56 -0
- dvt/cli/flags.py +558 -0
- dvt/cli/main.py +971 -0
- dvt/cli/option_types.py +121 -0
- dvt/cli/options.py +79 -0
- dvt/cli/params.py +803 -0
- dvt/cli/requires.py +478 -0
- dvt/cli/resolvers.py +32 -0
- dvt/cli/types.py +40 -0
- dvt/clients/__init__.py +0 -0
- dvt/clients/checked_load.py +82 -0
- dvt/clients/git.py +164 -0
- dvt/clients/jinja.py +206 -0
- dvt/clients/jinja_static.py +245 -0
- dvt/clients/registry.py +192 -0
- dvt/clients/yaml_helper.py +68 -0
- dvt/compilation.py +833 -0
- dvt/compute/__init__.py +26 -0
- dvt/compute/base.py +288 -0
- dvt/compute/engines/__init__.py +13 -0
- dvt/compute/engines/duckdb_engine.py +368 -0
- dvt/compute/engines/spark_engine.py +273 -0
- dvt/compute/query_analyzer.py +212 -0
- dvt/compute/router.py +483 -0
- dvt/config/__init__.py +4 -0
- dvt/config/catalogs.py +95 -0
- dvt/config/compute_config.py +406 -0
- dvt/config/profile.py +411 -0
- dvt/config/profiles_v2.py +464 -0
- dvt/config/project.py +893 -0
- dvt/config/renderer.py +232 -0
- dvt/config/runtime.py +491 -0
- dvt/config/selectors.py +209 -0
- dvt/config/utils.py +78 -0
- dvt/connectors/.gitignore +6 -0
- dvt/connectors/README.md +306 -0
- dvt/connectors/catalog.yml +217 -0
- dvt/connectors/download_connectors.py +300 -0
- dvt/constants.py +29 -0
- dvt/context/__init__.py +0 -0
- dvt/context/base.py +746 -0
- dvt/context/configured.py +136 -0
- dvt/context/context_config.py +350 -0
- dvt/context/docs.py +82 -0
- dvt/context/exceptions_jinja.py +179 -0
- dvt/context/macro_resolver.py +195 -0
- dvt/context/macros.py +171 -0
- dvt/context/manifest.py +73 -0
- dvt/context/providers.py +2198 -0
- dvt/context/query_header.py +14 -0
- dvt/context/secret.py +59 -0
- dvt/context/target.py +74 -0
- dvt/contracts/__init__.py +0 -0
- dvt/contracts/files.py +413 -0
- dvt/contracts/graph/__init__.py +0 -0
- dvt/contracts/graph/manifest.py +1904 -0
- dvt/contracts/graph/metrics.py +98 -0
- dvt/contracts/graph/model_config.py +71 -0
- dvt/contracts/graph/node_args.py +42 -0
- dvt/contracts/graph/nodes.py +1806 -0
- dvt/contracts/graph/semantic_manifest.py +233 -0
- dvt/contracts/graph/unparsed.py +812 -0
- dvt/contracts/project.py +417 -0
- dvt/contracts/results.py +53 -0
- dvt/contracts/selection.py +23 -0
- dvt/contracts/sql.py +86 -0
- dvt/contracts/state.py +69 -0
- dvt/contracts/util.py +46 -0
- dvt/deprecations.py +347 -0
- dvt/deps/__init__.py +0 -0
- dvt/deps/base.py +153 -0
- dvt/deps/git.py +196 -0
- dvt/deps/local.py +80 -0
- dvt/deps/registry.py +131 -0
- dvt/deps/resolver.py +149 -0
- dvt/deps/tarball.py +121 -0
- dvt/docs/source/_ext/dbt_click.py +118 -0
- dvt/docs/source/conf.py +32 -0
- dvt/env_vars.py +64 -0
- dvt/event_time/event_time.py +40 -0
- dvt/event_time/sample_window.py +60 -0
- dvt/events/__init__.py +16 -0
- dvt/events/base_types.py +37 -0
- dvt/events/core_types_pb2.py +2 -0
- dvt/events/logging.py +109 -0
- dvt/events/types.py +2534 -0
- dvt/exceptions.py +1487 -0
- dvt/flags.py +89 -0
- dvt/graph/__init__.py +11 -0
- dvt/graph/cli.py +248 -0
- dvt/graph/graph.py +172 -0
- dvt/graph/queue.py +213 -0
- dvt/graph/selector.py +375 -0
- dvt/graph/selector_methods.py +976 -0
- dvt/graph/selector_spec.py +223 -0
- dvt/graph/thread_pool.py +18 -0
- dvt/hooks.py +21 -0
- dvt/include/README.md +49 -0
- dvt/include/__init__.py +3 -0
- dvt/include/global_project.py +4 -0
- dvt/include/starter_project/.gitignore +4 -0
- dvt/include/starter_project/README.md +15 -0
- dvt/include/starter_project/__init__.py +3 -0
- dvt/include/starter_project/analyses/.gitkeep +0 -0
- dvt/include/starter_project/dvt_project.yml +36 -0
- dvt/include/starter_project/macros/.gitkeep +0 -0
- dvt/include/starter_project/models/example/my_first_dbt_model.sql +27 -0
- dvt/include/starter_project/models/example/my_second_dbt_model.sql +6 -0
- dvt/include/starter_project/models/example/schema.yml +21 -0
- dvt/include/starter_project/seeds/.gitkeep +0 -0
- dvt/include/starter_project/snapshots/.gitkeep +0 -0
- dvt/include/starter_project/tests/.gitkeep +0 -0
- dvt/internal_deprecations.py +27 -0
- dvt/jsonschemas/__init__.py +3 -0
- dvt/jsonschemas/jsonschemas.py +309 -0
- dvt/jsonschemas/project/0.0.110.json +4717 -0
- dvt/jsonschemas/project/0.0.85.json +2015 -0
- dvt/jsonschemas/resources/0.0.110.json +2636 -0
- dvt/jsonschemas/resources/0.0.85.json +2536 -0
- dvt/jsonschemas/resources/latest.json +6773 -0
- dvt/links.py +4 -0
- dvt/materializations/__init__.py +0 -0
- dvt/materializations/incremental/__init__.py +0 -0
- dvt/materializations/incremental/microbatch.py +235 -0
- dvt/mp_context.py +8 -0
- dvt/node_types.py +37 -0
- dvt/parser/__init__.py +23 -0
- dvt/parser/analysis.py +21 -0
- dvt/parser/base.py +549 -0
- dvt/parser/common.py +267 -0
- dvt/parser/docs.py +52 -0
- dvt/parser/fixtures.py +51 -0
- dvt/parser/functions.py +30 -0
- dvt/parser/generic_test.py +100 -0
- dvt/parser/generic_test_builders.py +334 -0
- dvt/parser/hooks.py +119 -0
- dvt/parser/macros.py +137 -0
- dvt/parser/manifest.py +2204 -0
- dvt/parser/models.py +574 -0
- dvt/parser/partial.py +1179 -0
- dvt/parser/read_files.py +445 -0
- dvt/parser/schema_generic_tests.py +423 -0
- dvt/parser/schema_renderer.py +111 -0
- dvt/parser/schema_yaml_readers.py +936 -0
- dvt/parser/schemas.py +1467 -0
- dvt/parser/search.py +149 -0
- dvt/parser/seeds.py +28 -0
- dvt/parser/singular_test.py +20 -0
- dvt/parser/snapshots.py +44 -0
- dvt/parser/sources.py +557 -0
- dvt/parser/sql.py +63 -0
- dvt/parser/unit_tests.py +622 -0
- dvt/plugins/__init__.py +20 -0
- dvt/plugins/contracts.py +10 -0
- dvt/plugins/exceptions.py +2 -0
- dvt/plugins/manager.py +164 -0
- dvt/plugins/manifest.py +21 -0
- dvt/profiler.py +20 -0
- dvt/py.typed +1 -0
- dvt/runners/__init__.py +2 -0
- dvt/runners/exposure_runner.py +7 -0
- dvt/runners/no_op_runner.py +46 -0
- dvt/runners/saved_query_runner.py +7 -0
- dvt/selected_resources.py +8 -0
- dvt/task/__init__.py +0 -0
- dvt/task/base.py +504 -0
- dvt/task/build.py +197 -0
- dvt/task/clean.py +57 -0
- dvt/task/clone.py +162 -0
- dvt/task/compile.py +151 -0
- dvt/task/compute.py +366 -0
- dvt/task/debug.py +650 -0
- dvt/task/deps.py +280 -0
- dvt/task/docs/__init__.py +3 -0
- dvt/task/docs/generate.py +408 -0
- dvt/task/docs/index.html +250 -0
- dvt/task/docs/serve.py +28 -0
- dvt/task/freshness.py +323 -0
- dvt/task/function.py +122 -0
- dvt/task/group_lookup.py +46 -0
- dvt/task/init.py +374 -0
- dvt/task/list.py +237 -0
- dvt/task/printer.py +176 -0
- dvt/task/profiles.py +256 -0
- dvt/task/retry.py +175 -0
- dvt/task/run.py +1146 -0
- dvt/task/run_operation.py +142 -0
- dvt/task/runnable.py +802 -0
- dvt/task/seed.py +104 -0
- dvt/task/show.py +150 -0
- dvt/task/snapshot.py +57 -0
- dvt/task/sql.py +111 -0
- dvt/task/test.py +464 -0
- dvt/tests/fixtures/__init__.py +1 -0
- dvt/tests/fixtures/project.py +620 -0
- dvt/tests/util.py +651 -0
- dvt/tracking.py +529 -0
- dvt/utils/__init__.py +3 -0
- dvt/utils/artifact_upload.py +151 -0
- dvt/utils/utils.py +408 -0
- dvt/version.py +249 -0
- dvt_core-1.11.0b4.dist-info/METADATA +252 -0
- dvt_core-1.11.0b4.dist-info/RECORD +261 -0
- dvt_core-1.11.0b4.dist-info/WHEEL +5 -0
- dvt_core-1.11.0b4.dist-info/entry_points.txt +2 -0
- dvt_core-1.11.0b4.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os
|
|
3
|
+
import re
|
|
4
|
+
from datetime import date, datetime
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Any, Dict, Iterator, List, Optional, Union
|
|
7
|
+
|
|
8
|
+
import jsonschema
|
|
9
|
+
from dvt import deprecations
|
|
10
|
+
from dvt.jsonschemas import JSONSCHEMAS_PATH
|
|
11
|
+
from jsonschema import ValidationError
|
|
12
|
+
from jsonschema._keywords import type as type_rule
|
|
13
|
+
from jsonschema.validators import Draft7Validator, extend
|
|
14
|
+
|
|
15
|
+
from dbt_common.context import get_invocation_context
|
|
16
|
+
|
|
17
|
+
_PROJECT_SCHEMA: Optional[Dict[str, Any]] = None
|
|
18
|
+
_RESOURCES_SCHEMA: Optional[Dict[str, Any]] = None
|
|
19
|
+
|
|
20
|
+
_JSONSCHEMA_SUPPORTED_ADAPTERS = {
|
|
21
|
+
"bigquery",
|
|
22
|
+
"databricks",
|
|
23
|
+
"redshift",
|
|
24
|
+
"snowflake",
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
_HIERARCHICAL_CONFIG_KEYS = {
|
|
28
|
+
"seeds",
|
|
29
|
+
"sources",
|
|
30
|
+
"models",
|
|
31
|
+
"snapshots",
|
|
32
|
+
"tests",
|
|
33
|
+
"exposures",
|
|
34
|
+
"data_tests",
|
|
35
|
+
"metrics",
|
|
36
|
+
"saved_queries",
|
|
37
|
+
"semantic_models",
|
|
38
|
+
"unit_tests",
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def load_json_from_package(jsonschema_type: str, filename: str) -> Dict[str, Any]:
|
|
43
|
+
"""Loads a JSON file from within a package."""
|
|
44
|
+
|
|
45
|
+
path = Path(JSONSCHEMAS_PATH).joinpath(jsonschema_type, filename)
|
|
46
|
+
data = path.read_bytes()
|
|
47
|
+
return json.loads(data)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def project_schema() -> Dict[str, Any]:
|
|
51
|
+
global _PROJECT_SCHEMA
|
|
52
|
+
|
|
53
|
+
if _PROJECT_SCHEMA is None:
|
|
54
|
+
_PROJECT_SCHEMA = load_json_from_package(
|
|
55
|
+
jsonschema_type="project", filename="0.0.110.json"
|
|
56
|
+
)
|
|
57
|
+
return _PROJECT_SCHEMA
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def resources_schema() -> Dict[str, Any]:
|
|
61
|
+
global _RESOURCES_SCHEMA
|
|
62
|
+
|
|
63
|
+
if _RESOURCES_SCHEMA is None:
|
|
64
|
+
_RESOURCES_SCHEMA = load_json_from_package(
|
|
65
|
+
jsonschema_type="resources", filename="latest.json"
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
return _RESOURCES_SCHEMA
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def custom_type_rule(validator, types, instance, schema):
|
|
72
|
+
"""This is necessary because PyYAML loads things that look like dates or datetimes as those
|
|
73
|
+
python objects. Then jsonschema.validate() fails because it expects strings.
|
|
74
|
+
"""
|
|
75
|
+
if "string" in types and (isinstance(instance, datetime) or isinstance(instance, date)):
|
|
76
|
+
return
|
|
77
|
+
else:
|
|
78
|
+
return type_rule(validator, types, instance, schema)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
CustomDraft7Validator = extend(Draft7Validator, validators={"type": custom_type_rule})
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def error_path_to_string(error: jsonschema.ValidationError) -> str:
|
|
85
|
+
if len(error.path) == 0:
|
|
86
|
+
return ""
|
|
87
|
+
else:
|
|
88
|
+
path = str(error.path.popleft())
|
|
89
|
+
for part in error.path:
|
|
90
|
+
if isinstance(part, int):
|
|
91
|
+
path += f"[{part}]"
|
|
92
|
+
else:
|
|
93
|
+
path += f".{part}"
|
|
94
|
+
|
|
95
|
+
return path
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def _additional_properties_violation_keys(error: ValidationError) -> List[str]:
|
|
99
|
+
found_keys = re.findall(r"'\S+'", error.message)
|
|
100
|
+
return [key.strip("'") for key in found_keys]
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def _validate_with_schema(
|
|
104
|
+
schema: Dict[str, Any], json: Dict[str, Any]
|
|
105
|
+
) -> Iterator[ValidationError]:
|
|
106
|
+
validator = CustomDraft7Validator(schema)
|
|
107
|
+
return validator.iter_errors(json)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def _get_allowed_config_fields_from_error_path(
|
|
111
|
+
yml_schema: Dict[str, Any], error_path: List[Union[str, int]]
|
|
112
|
+
) -> Optional[List[str]]:
|
|
113
|
+
property_field_name = None
|
|
114
|
+
node_schema = yml_schema["properties"]
|
|
115
|
+
for part in error_path:
|
|
116
|
+
if isinstance(part, str):
|
|
117
|
+
if part in node_schema:
|
|
118
|
+
if "items" not in node_schema[part]:
|
|
119
|
+
break
|
|
120
|
+
|
|
121
|
+
# Update property field name
|
|
122
|
+
property_field_name = node_schema[part]["items"]["$ref"].split("/")[-1]
|
|
123
|
+
|
|
124
|
+
# Jump to the next level of the schema
|
|
125
|
+
item_definition = node_schema[part]["items"]["$ref"].split("/")[-1]
|
|
126
|
+
node_schema = yml_schema["definitions"][item_definition]["properties"]
|
|
127
|
+
|
|
128
|
+
if not property_field_name:
|
|
129
|
+
return None
|
|
130
|
+
|
|
131
|
+
if "config" not in yml_schema["definitions"][property_field_name]["properties"]:
|
|
132
|
+
return None
|
|
133
|
+
|
|
134
|
+
config_field_name = yml_schema["definitions"][property_field_name]["properties"]["config"][
|
|
135
|
+
"anyOf"
|
|
136
|
+
][0]["$ref"].split("/")[-1]
|
|
137
|
+
|
|
138
|
+
allowed_config_fields = list(set(yml_schema["definitions"][config_field_name]["properties"]))
|
|
139
|
+
|
|
140
|
+
return allowed_config_fields
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def _can_run_validations() -> bool:
|
|
144
|
+
if not os.environ.get("DBT_ENV_PRIVATE_RUN_JSONSCHEMA_VALIDATIONS"):
|
|
145
|
+
return False
|
|
146
|
+
|
|
147
|
+
invocation_context = get_invocation_context()
|
|
148
|
+
return invocation_context.adapter_types.issubset(_JSONSCHEMA_SUPPORTED_ADAPTERS)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def jsonschema_validate(schema: Dict[str, Any], json: Dict[str, Any], file_path: str) -> None:
|
|
152
|
+
if not _can_run_validations():
|
|
153
|
+
return
|
|
154
|
+
|
|
155
|
+
errors = _validate_with_schema(schema, json)
|
|
156
|
+
for error in errors:
|
|
157
|
+
# Listify the error path to make it easier to work with (it's a deque in the ValidationError object)
|
|
158
|
+
error_path = list(error.path)
|
|
159
|
+
if error.validator == "additionalProperties":
|
|
160
|
+
keys = _additional_properties_violation_keys(error)
|
|
161
|
+
if len(error.path) == 0:
|
|
162
|
+
for key in keys:
|
|
163
|
+
deprecations.warn(
|
|
164
|
+
"custom-top-level-key-deprecation",
|
|
165
|
+
msg="Unexpected top-level key" + (" " + key if key else ""),
|
|
166
|
+
file=file_path,
|
|
167
|
+
)
|
|
168
|
+
else:
|
|
169
|
+
key_path = error_path_to_string(error)
|
|
170
|
+
for key in keys:
|
|
171
|
+
if key == "overrides" and key_path.startswith("sources"):
|
|
172
|
+
|
|
173
|
+
deprecations.warn(
|
|
174
|
+
"source-override-deprecation",
|
|
175
|
+
source_name=key_path.split(".")[-1],
|
|
176
|
+
file=file_path,
|
|
177
|
+
)
|
|
178
|
+
else:
|
|
179
|
+
allowed_config_fields = _get_allowed_config_fields_from_error_path(
|
|
180
|
+
schema, error_path
|
|
181
|
+
)
|
|
182
|
+
if allowed_config_fields and key in allowed_config_fields:
|
|
183
|
+
deprecations.warn(
|
|
184
|
+
"property-moved-to-config-deprecation",
|
|
185
|
+
key=key,
|
|
186
|
+
file=file_path,
|
|
187
|
+
key_path=key_path,
|
|
188
|
+
)
|
|
189
|
+
else:
|
|
190
|
+
deprecations.warn(
|
|
191
|
+
"custom-key-in-object-deprecation",
|
|
192
|
+
key=key,
|
|
193
|
+
file=file_path,
|
|
194
|
+
key_path=key_path,
|
|
195
|
+
)
|
|
196
|
+
elif error.validator == "anyOf" and len(error_path) > 0:
|
|
197
|
+
sub_errors = error.context or []
|
|
198
|
+
# schema yaml resource configs
|
|
199
|
+
if error_path[-1] == "config":
|
|
200
|
+
for sub_error in sub_errors:
|
|
201
|
+
if (
|
|
202
|
+
isinstance(sub_error, ValidationError)
|
|
203
|
+
and sub_error.validator == "additionalProperties"
|
|
204
|
+
):
|
|
205
|
+
keys = _additional_properties_violation_keys(sub_error)
|
|
206
|
+
key_path = error_path_to_string(error)
|
|
207
|
+
for key in keys:
|
|
208
|
+
deprecations.warn(
|
|
209
|
+
"custom-key-in-config-deprecation",
|
|
210
|
+
key=key,
|
|
211
|
+
file=file_path,
|
|
212
|
+
key_path=key_path,
|
|
213
|
+
)
|
|
214
|
+
# dbt_project.yml configs
|
|
215
|
+
elif "dbt_project.yml" in file_path and error_path[0] in _HIERARCHICAL_CONFIG_KEYS:
|
|
216
|
+
for sub_error in sub_errors:
|
|
217
|
+
if isinstance(sub_error, ValidationError) and sub_error.validator == "type":
|
|
218
|
+
# Only raise type-errors if they are indicating leaf config without a plus prefix
|
|
219
|
+
if (
|
|
220
|
+
len(sub_error.path) > 0
|
|
221
|
+
and isinstance(sub_error.path[-1], str)
|
|
222
|
+
and not sub_error.path[-1].startswith("+")
|
|
223
|
+
):
|
|
224
|
+
deprecations.warn(
|
|
225
|
+
"missing-plus-prefix-in-config-deprecation",
|
|
226
|
+
key=sub_error.path[-1],
|
|
227
|
+
file=file_path,
|
|
228
|
+
key_path=error_path_to_string(sub_error),
|
|
229
|
+
)
|
|
230
|
+
elif error.validator == "type":
|
|
231
|
+
# Not deprecating invalid types yet
|
|
232
|
+
pass
|
|
233
|
+
else:
|
|
234
|
+
deprecations.warn(
|
|
235
|
+
"generic-json-schema-validation-deprecation",
|
|
236
|
+
violation=error.message,
|
|
237
|
+
file=file_path,
|
|
238
|
+
key_path=error_path_to_string(error),
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def validate_model_config(config: Dict[str, Any], file_path: str) -> None:
|
|
243
|
+
if not _can_run_validations():
|
|
244
|
+
return
|
|
245
|
+
|
|
246
|
+
resources_jsonschema = resources_schema()
|
|
247
|
+
nested_definition_name = "ModelConfig"
|
|
248
|
+
|
|
249
|
+
model_config_schema = {
|
|
250
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
251
|
+
"title": nested_definition_name,
|
|
252
|
+
**resources_jsonschema["definitions"][nested_definition_name],
|
|
253
|
+
"definitions": {
|
|
254
|
+
k: v
|
|
255
|
+
for k, v in resources_jsonschema["definitions"].items()
|
|
256
|
+
if k != nested_definition_name
|
|
257
|
+
},
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
errors = _validate_with_schema(model_config_schema, config)
|
|
261
|
+
for error in errors:
|
|
262
|
+
error_path = list(error.path)
|
|
263
|
+
if error.validator == "additionalProperties":
|
|
264
|
+
keys = _additional_properties_violation_keys(error)
|
|
265
|
+
if len(error.path) == 0:
|
|
266
|
+
key_path = error_path_to_string(error)
|
|
267
|
+
for key in keys:
|
|
268
|
+
deprecations.warn(
|
|
269
|
+
"custom-key-in-config-deprecation",
|
|
270
|
+
key=key,
|
|
271
|
+
file=file_path,
|
|
272
|
+
key_path=key_path,
|
|
273
|
+
)
|
|
274
|
+
else:
|
|
275
|
+
error.path.appendleft("config")
|
|
276
|
+
key_path = error_path_to_string(error)
|
|
277
|
+
for key in keys:
|
|
278
|
+
deprecations.warn(
|
|
279
|
+
"custom-key-in-object-deprecation",
|
|
280
|
+
key=key,
|
|
281
|
+
file=file_path,
|
|
282
|
+
key_path=key_path,
|
|
283
|
+
)
|
|
284
|
+
elif error.validator == "type":
|
|
285
|
+
# Not deprecating invalid types yet, except for pre-existing deprecation_date deprecation
|
|
286
|
+
pass
|
|
287
|
+
elif error.validator == "anyOf" and len(error_path) > 0:
|
|
288
|
+
for sub_error in error.context or []:
|
|
289
|
+
if (
|
|
290
|
+
isinstance(sub_error, ValidationError)
|
|
291
|
+
and sub_error.validator == "additionalProperties"
|
|
292
|
+
):
|
|
293
|
+
error.path.appendleft("config")
|
|
294
|
+
keys = _additional_properties_violation_keys(sub_error)
|
|
295
|
+
key_path = error_path_to_string(error)
|
|
296
|
+
for key in keys:
|
|
297
|
+
deprecations.warn(
|
|
298
|
+
"custom-key-in-object-deprecation",
|
|
299
|
+
key=key,
|
|
300
|
+
file=file_path,
|
|
301
|
+
key_path=key_path,
|
|
302
|
+
)
|
|
303
|
+
else:
|
|
304
|
+
deprecations.warn(
|
|
305
|
+
"generic-json-schema-validation-deprecation",
|
|
306
|
+
violation=error.message,
|
|
307
|
+
file=file_path,
|
|
308
|
+
key_path=error_path_to_string(error),
|
|
309
|
+
)
|