dvt-core 0.59.0a51__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.
- 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 +2660 -0
- dbt/cli/option_types.py +121 -0
- dbt/cli/options.py +80 -0
- dbt/cli/params.py +844 -0
- dbt/cli/requires.py +490 -0
- dbt/cli/resolvers.py +60 -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 +642 -0
- dbt/compute/federated_executor.py +1080 -0
- dbt/compute/filter_pushdown.py +273 -0
- dbt/compute/jar_provisioning.py +273 -0
- dbt/compute/java_compat.py +689 -0
- dbt/compute/jdbc_utils.py +1252 -0
- dbt/compute/metadata/__init__.py +63 -0
- dbt/compute/metadata/adapters_registry.py +370 -0
- dbt/compute/metadata/catalog_store.py +1036 -0
- dbt/compute/metadata/registry.py +674 -0
- dbt/compute/metadata/store.py +1020 -0
- dbt/compute/smart_selector.py +377 -0
- dbt/compute/spark_logger.py +272 -0
- dbt/compute/strategies/__init__.py +55 -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 +472 -0
- dbt/compute/strategies/standalone.py +262 -0
- dbt/config/__init__.py +4 -0
- dbt/config/catalogs.py +94 -0
- dbt/config/compute.py +513 -0
- dbt/config/dvt_profile.py +408 -0
- dbt/config/profile.py +422 -0
- dbt/config/project.py +888 -0
- dbt/config/project_utils.py +48 -0
- dbt/config/renderer.py +231 -0
- dbt/config/runtime.py +564 -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 +419 -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 +348 -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 +249 -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/data/adapters_registry.duckdb +0 -0
- dbt/include/data/build_comprehensive_registry.py +1254 -0
- dbt/include/data/build_registry.py +242 -0
- dbt/include/data/csv/adapter_queries.csv +33 -0
- dbt/include/data/csv/syntax_rules.csv +9 -0
- dbt/include/data/csv/type_mappings_bigquery.csv +28 -0
- dbt/include/data/csv/type_mappings_databricks.csv +30 -0
- dbt/include/data/csv/type_mappings_mysql.csv +40 -0
- dbt/include/data/csv/type_mappings_oracle.csv +30 -0
- dbt/include/data/csv/type_mappings_postgres.csv +56 -0
- dbt/include/data/csv/type_mappings_redshift.csv +33 -0
- dbt/include/data/csv/type_mappings_snowflake.csv +38 -0
- dbt/include/data/csv/type_mappings_sqlserver.csv +35 -0
- dbt/include/dvt_starter_project/README.md +15 -0
- dbt/include/dvt_starter_project/__init__.py +3 -0
- dbt/include/dvt_starter_project/analyses/PLACEHOLDER +0 -0
- dbt/include/dvt_starter_project/dvt_project.yml +39 -0
- dbt/include/dvt_starter_project/logs/PLACEHOLDER +0 -0
- dbt/include/dvt_starter_project/macros/PLACEHOLDER +0 -0
- dbt/include/dvt_starter_project/models/example/my_first_dbt_model.sql +27 -0
- dbt/include/dvt_starter_project/models/example/my_second_dbt_model.sql +6 -0
- dbt/include/dvt_starter_project/models/example/schema.yml +21 -0
- dbt/include/dvt_starter_project/seeds/PLACEHOLDER +0 -0
- dbt/include/dvt_starter_project/snapshots/PLACEHOLDER +0 -0
- dbt/include/dvt_starter_project/tests/PLACEHOLDER +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 +122 -0
- dbt/parser/macros.py +137 -0
- dbt/parser/manifest.py +2208 -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.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 +506 -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 +458 -0
- dbt/task/debug.py +513 -0
- dbt/task/deps.py +280 -0
- dbt/task/docs/__init__.py +3 -0
- dbt/task/docs/api/__init__.py +23 -0
- dbt/task/docs/api/catalog.py +204 -0
- dbt/task/docs/api/lineage.py +234 -0
- dbt/task/docs/api/profile.py +204 -0
- dbt/task/docs/api/spark.py +186 -0
- dbt/task/docs/generate.py +1002 -0
- dbt/task/docs/index.html +250 -0
- dbt/task/docs/serve.py +174 -0
- dbt/task/dvt_output.py +509 -0
- dbt/task/dvt_run.py +282 -0
- dbt/task/dvt_seed.py +806 -0
- dbt/task/freshness.py +322 -0
- dbt/task/function.py +121 -0
- dbt/task/group_lookup.py +46 -0
- dbt/task/init.py +1022 -0
- dbt/task/java.py +316 -0
- dbt/task/list.py +236 -0
- dbt/task/metadata.py +804 -0
- dbt/task/migrate.py +714 -0
- dbt/task/printer.py +175 -0
- dbt/task/profile.py +1489 -0
- dbt/task/profile_serve.py +662 -0
- dbt/task/retract.py +441 -0
- dbt/task/retry.py +175 -0
- dbt/task/run.py +1647 -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 +814 -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 +271 -0
- dvt_cli/__init__.py +158 -0
- dvt_core-0.59.0a51.dist-info/METADATA +288 -0
- dvt_core-0.59.0a51.dist-info/RECORD +299 -0
- dvt_core-0.59.0a51.dist-info/WHEEL +5 -0
- dvt_core-0.59.0a51.dist-info/entry_points.txt +2 -0
- dvt_core-0.59.0a51.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from dataclasses import dataclass, field
|
|
3
|
+
from typing import Any, Dict, List, Optional, Union
|
|
4
|
+
|
|
5
|
+
from mashumaro.jsonschema.annotations import Pattern
|
|
6
|
+
from typing_extensions import Annotated
|
|
7
|
+
|
|
8
|
+
from dbt import hooks
|
|
9
|
+
from dbt.artifacts.resources.base import Docs
|
|
10
|
+
from dbt.artifacts.resources.types import ModelHookType
|
|
11
|
+
from dbt.artifacts.utils.validation import validate_color
|
|
12
|
+
from dbt_common.contracts.config.base import BaseConfig, CompareBehavior, MergeBehavior
|
|
13
|
+
from dbt_common.contracts.config.materialization import OnConfigurationChangeOption
|
|
14
|
+
from dbt_common.contracts.config.metadata import Metadata, ShowBehavior
|
|
15
|
+
from dbt_common.dataclass_schema import ValidationError, dbtClassMixin
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def list_str() -> List[str]:
|
|
19
|
+
return []
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class Severity(str):
|
|
23
|
+
pass
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def metas(*metas: Metadata) -> Dict[str, Any]:
|
|
27
|
+
existing: Dict[str, Any] = {}
|
|
28
|
+
for m in metas:
|
|
29
|
+
existing = m.meta(existing)
|
|
30
|
+
return existing
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@dataclass
|
|
34
|
+
class ContractConfig(dbtClassMixin):
|
|
35
|
+
enforced: bool = False
|
|
36
|
+
alias_types: bool = True
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@dataclass
|
|
40
|
+
class Hook(dbtClassMixin):
|
|
41
|
+
sql: str
|
|
42
|
+
transaction: bool = True
|
|
43
|
+
index: Optional[int] = None
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@dataclass
|
|
47
|
+
class NodeAndTestConfig(BaseConfig):
|
|
48
|
+
enabled: bool = True
|
|
49
|
+
# these fields are included in serialized output, but are not part of
|
|
50
|
+
# config comparison (they are part of database_representation)
|
|
51
|
+
alias: Optional[str] = field(
|
|
52
|
+
default=None,
|
|
53
|
+
metadata=CompareBehavior.Exclude.meta(),
|
|
54
|
+
)
|
|
55
|
+
schema: Optional[str] = field(
|
|
56
|
+
default=None,
|
|
57
|
+
metadata=CompareBehavior.Exclude.meta(),
|
|
58
|
+
)
|
|
59
|
+
database: Optional[str] = field(
|
|
60
|
+
default=None,
|
|
61
|
+
metadata=CompareBehavior.Exclude.meta(),
|
|
62
|
+
)
|
|
63
|
+
tags: Union[List[str], str] = field(
|
|
64
|
+
default_factory=list_str,
|
|
65
|
+
metadata=metas(ShowBehavior.Hide, MergeBehavior.Append, CompareBehavior.Exclude),
|
|
66
|
+
)
|
|
67
|
+
meta: Dict[str, Any] = field(
|
|
68
|
+
default_factory=dict,
|
|
69
|
+
metadata=MergeBehavior.Update.meta(),
|
|
70
|
+
)
|
|
71
|
+
group: Optional[str] = field(
|
|
72
|
+
default=None,
|
|
73
|
+
metadata=CompareBehavior.Exclude.meta(),
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@dataclass
|
|
78
|
+
class NodeConfig(NodeAndTestConfig):
|
|
79
|
+
# Note: if any new fields are added with MergeBehavior, also update the
|
|
80
|
+
# 'mergebehavior' dictionary
|
|
81
|
+
materialized: str = "view"
|
|
82
|
+
incremental_strategy: Optional[str] = None
|
|
83
|
+
batch_size: Any = None
|
|
84
|
+
lookback: Any = 1
|
|
85
|
+
begin: Any = None
|
|
86
|
+
persist_docs: Dict[str, Any] = field(default_factory=dict)
|
|
87
|
+
post_hook: List[Hook] = field(
|
|
88
|
+
default_factory=list,
|
|
89
|
+
metadata={"merge": MergeBehavior.Append, "alias": "post-hook"},
|
|
90
|
+
)
|
|
91
|
+
pre_hook: List[Hook] = field(
|
|
92
|
+
default_factory=list,
|
|
93
|
+
metadata={"merge": MergeBehavior.Append, "alias": "pre-hook"},
|
|
94
|
+
)
|
|
95
|
+
quoting: Dict[str, Any] = field(
|
|
96
|
+
default_factory=dict,
|
|
97
|
+
metadata=MergeBehavior.Update.meta(),
|
|
98
|
+
)
|
|
99
|
+
# This is actually only used by seeds. Should it be available to others?
|
|
100
|
+
# That would be a breaking change!
|
|
101
|
+
column_types: Dict[str, Any] = field(
|
|
102
|
+
default_factory=dict,
|
|
103
|
+
metadata=MergeBehavior.Update.meta(),
|
|
104
|
+
)
|
|
105
|
+
full_refresh: Optional[bool] = None
|
|
106
|
+
# 'unique_key' doesn't use 'Optional' because typing.get_type_hints was
|
|
107
|
+
# sometimes getting the Union order wrong, causing serialization failures.
|
|
108
|
+
unique_key: Union[str, List[str], None] = None
|
|
109
|
+
on_schema_change: Optional[str] = "ignore"
|
|
110
|
+
on_configuration_change: OnConfigurationChangeOption = field(
|
|
111
|
+
default_factory=OnConfigurationChangeOption.default
|
|
112
|
+
)
|
|
113
|
+
grants: Dict[str, Any] = field(
|
|
114
|
+
default_factory=dict, metadata=MergeBehavior.DictKeyAppend.meta()
|
|
115
|
+
)
|
|
116
|
+
packages: List[str] = field(
|
|
117
|
+
default_factory=list,
|
|
118
|
+
metadata=MergeBehavior.Append.meta(),
|
|
119
|
+
)
|
|
120
|
+
docs: Docs = field(
|
|
121
|
+
default_factory=Docs,
|
|
122
|
+
metadata=MergeBehavior.Update.meta(),
|
|
123
|
+
)
|
|
124
|
+
contract: ContractConfig = field(
|
|
125
|
+
default_factory=ContractConfig,
|
|
126
|
+
metadata=MergeBehavior.Update.meta(),
|
|
127
|
+
)
|
|
128
|
+
event_time: Any = None
|
|
129
|
+
concurrent_batches: Any = None
|
|
130
|
+
# DVT-specific configuration fields
|
|
131
|
+
target: Optional[str] = field(
|
|
132
|
+
default=None,
|
|
133
|
+
metadata=CompareBehavior.Exclude.meta(),
|
|
134
|
+
) # Target connection for materialization
|
|
135
|
+
compute: Optional[str] = field(
|
|
136
|
+
default=None,
|
|
137
|
+
metadata=CompareBehavior.Exclude.meta(),
|
|
138
|
+
) # Compute engine override (spark-local/spark-cluster/etc.)
|
|
139
|
+
|
|
140
|
+
def __post_init__(self):
|
|
141
|
+
# we validate that node_color has a suitable value to prevent dbt-docs from crashing
|
|
142
|
+
if self.docs.node_color:
|
|
143
|
+
node_color = self.docs.node_color
|
|
144
|
+
if not validate_color(node_color):
|
|
145
|
+
raise ValidationError(
|
|
146
|
+
f"Invalid color name for docs.node_color: {node_color}. "
|
|
147
|
+
"It is neither a valid HTML color name nor a valid HEX code."
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
if (
|
|
151
|
+
self.contract.enforced
|
|
152
|
+
and self.materialized == "incremental"
|
|
153
|
+
and self.on_schema_change not in ("append_new_columns", "fail")
|
|
154
|
+
):
|
|
155
|
+
raise ValidationError(
|
|
156
|
+
f"Invalid value for on_schema_change: {self.on_schema_change}. Models "
|
|
157
|
+
"materialized as incremental with contracts enabled must set "
|
|
158
|
+
"on_schema_change to 'append_new_columns' or 'fail'"
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
@classmethod
|
|
162
|
+
def __pre_deserialize__(cls, data):
|
|
163
|
+
data = super().__pre_deserialize__(data)
|
|
164
|
+
for key in ModelHookType:
|
|
165
|
+
if key in data:
|
|
166
|
+
data[key] = [hooks.get_hook_dict(h) for h in data[key]]
|
|
167
|
+
return data
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
SEVERITY_PATTERN = r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$"
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
@dataclass
|
|
174
|
+
class TestConfig(NodeAndTestConfig):
|
|
175
|
+
__test__ = False
|
|
176
|
+
|
|
177
|
+
# this is repeated because of a different default
|
|
178
|
+
schema: Optional[str] = field(
|
|
179
|
+
default="dbt_test__audit",
|
|
180
|
+
metadata=CompareBehavior.Exclude.meta(),
|
|
181
|
+
)
|
|
182
|
+
materialized: str = "test"
|
|
183
|
+
# Annotated is used by mashumaro for jsonschema generation
|
|
184
|
+
severity: Annotated[Severity, Pattern(SEVERITY_PATTERN)] = Severity("ERROR")
|
|
185
|
+
store_failures: Optional[bool] = None
|
|
186
|
+
store_failures_as: Optional[str] = None
|
|
187
|
+
where: Optional[str] = None
|
|
188
|
+
limit: Optional[int] = None
|
|
189
|
+
fail_calc: str = "count(*)"
|
|
190
|
+
warn_if: str = "!= 0"
|
|
191
|
+
error_if: str = "!= 0"
|
|
192
|
+
|
|
193
|
+
def finalize_and_validate(self):
|
|
194
|
+
"""
|
|
195
|
+
The presence of a setting for `store_failures_as` overrides any existing setting for `store_failures`,
|
|
196
|
+
regardless of level of granularity. If `store_failures_as` is not set, then `store_failures` takes effect.
|
|
197
|
+
At the time of implementation, `store_failures = True` would always create a table; the user could not
|
|
198
|
+
configure this. Hence, if `store_failures = True` and `store_failures_as` is not specified, then it
|
|
199
|
+
should be set to "table" to mimic the existing functionality.
|
|
200
|
+
|
|
201
|
+
A side effect of this overriding functionality is that `store_failures_as="view"` at the project
|
|
202
|
+
level cannot be turned off at the model level without setting both `store_failures_as` and
|
|
203
|
+
`store_failures`. The former would cascade down and override `store_failures=False`. The proposal
|
|
204
|
+
is to include "ephemeral" as a value for `store_failures_as`, which effectively sets
|
|
205
|
+
`store_failures=False`.
|
|
206
|
+
|
|
207
|
+
The exception handling for this is tricky. If we raise an exception here, the entire run fails at
|
|
208
|
+
parse time. We would rather well-formed models run successfully, leaving only exceptions to be rerun
|
|
209
|
+
if necessary. Hence, the exception needs to be raised in the test materialization. In order to do so,
|
|
210
|
+
we need to make sure that we go down the `store_failures = True` route with the invalid setting for
|
|
211
|
+
`store_failures_as`. This results in the `.get()` defaulted to `True` below, instead of a normal
|
|
212
|
+
dictionary lookup as is done in the `if` block. Refer to the test materialization for the
|
|
213
|
+
exception that is raise as a result of an invalid value.
|
|
214
|
+
|
|
215
|
+
The intention of this block is to behave as if `store_failures_as` is the only setting,
|
|
216
|
+
but still allow for backwards compatibility for `store_failures`.
|
|
217
|
+
See https://github.com/dbt-labs/dbt-core/issues/6914 for more information.
|
|
218
|
+
"""
|
|
219
|
+
super().finalize_and_validate()
|
|
220
|
+
|
|
221
|
+
# if `store_failures_as` is not set, it gets set by `store_failures`
|
|
222
|
+
# the settings below mimic existing behavior prior to `store_failures_as`
|
|
223
|
+
get_store_failures_as_map = {
|
|
224
|
+
True: "table",
|
|
225
|
+
False: "ephemeral",
|
|
226
|
+
None: None,
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
# if `store_failures_as` is set, it dictates what `store_failures` gets set to
|
|
230
|
+
# the settings below overrides whatever `store_failures` is set to by the user
|
|
231
|
+
get_store_failures_map = {
|
|
232
|
+
"ephemeral": False,
|
|
233
|
+
"table": True,
|
|
234
|
+
"view": True,
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if self.store_failures_as is None:
|
|
238
|
+
self.store_failures_as = get_store_failures_as_map[self.store_failures]
|
|
239
|
+
else:
|
|
240
|
+
self.store_failures = get_store_failures_map.get(self.store_failures_as, True)
|
|
241
|
+
|
|
242
|
+
return self
|
|
243
|
+
|
|
244
|
+
@classmethod
|
|
245
|
+
def same_contents(cls, unrendered: Dict[str, Any], other: Dict[str, Any]) -> bool:
|
|
246
|
+
"""This is like __eq__, except it explicitly checks certain fields."""
|
|
247
|
+
modifiers = [
|
|
248
|
+
"severity",
|
|
249
|
+
"where",
|
|
250
|
+
"limit",
|
|
251
|
+
"fail_calc",
|
|
252
|
+
"warn_if",
|
|
253
|
+
"error_if",
|
|
254
|
+
"store_failures",
|
|
255
|
+
"store_failures_as",
|
|
256
|
+
]
|
|
257
|
+
|
|
258
|
+
seen = set()
|
|
259
|
+
for _, target_name in cls._get_fields():
|
|
260
|
+
key = target_name
|
|
261
|
+
seen.add(key)
|
|
262
|
+
if key in modifiers:
|
|
263
|
+
if not cls.compare_key(unrendered, other, key):
|
|
264
|
+
return False
|
|
265
|
+
return True
|
|
266
|
+
|
|
267
|
+
@classmethod
|
|
268
|
+
def validate(cls, data):
|
|
269
|
+
if data.get("severity") and not re.match(SEVERITY_PATTERN, data.get("severity")):
|
|
270
|
+
raise ValidationError(
|
|
271
|
+
f"Severity must be either 'warn' or 'error'. Got '{data.get('severity')}'"
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
super().validate(data)
|
|
275
|
+
|
|
276
|
+
if data.get("materialized") and data.get("materialized") != "test":
|
|
277
|
+
raise ValidationError("A test must have a materialized value of 'test'")
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Literal
|
|
3
|
+
|
|
4
|
+
from dbt.artifacts.resources.base import BaseResource
|
|
5
|
+
from dbt.artifacts.resources.types import NodeType
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass
|
|
9
|
+
class Documentation(BaseResource):
|
|
10
|
+
resource_type: Literal[NodeType.Documentation]
|
|
11
|
+
block_contents: str
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import time
|
|
2
|
+
from dataclasses import dataclass, field
|
|
3
|
+
from typing import Any, Dict, List, Literal, Optional
|
|
4
|
+
|
|
5
|
+
from dbt.artifacts.resources.base import GraphResource
|
|
6
|
+
from dbt.artifacts.resources.types import NodeType
|
|
7
|
+
from dbt.artifacts.resources.v1.components import DependsOn, RefArgs
|
|
8
|
+
from dbt.artifacts.resources.v1.owner import Owner
|
|
9
|
+
from dbt_common.contracts.config.base import BaseConfig
|
|
10
|
+
from dbt_common.dataclass_schema import StrEnum
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ExposureType(StrEnum):
|
|
14
|
+
Dashboard = "dashboard"
|
|
15
|
+
Notebook = "notebook"
|
|
16
|
+
Analysis = "analysis"
|
|
17
|
+
ML = "ml"
|
|
18
|
+
Application = "application"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class MaturityType(StrEnum):
|
|
22
|
+
Low = "low"
|
|
23
|
+
Medium = "medium"
|
|
24
|
+
High = "high"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@dataclass
|
|
28
|
+
class ExposureConfig(BaseConfig):
|
|
29
|
+
enabled: bool = True
|
|
30
|
+
tags: List[str] = field(default_factory=list)
|
|
31
|
+
meta: Dict[str, Any] = field(default_factory=dict)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@dataclass
|
|
35
|
+
class Exposure(GraphResource):
|
|
36
|
+
type: ExposureType
|
|
37
|
+
owner: Owner
|
|
38
|
+
resource_type: Literal[NodeType.Exposure]
|
|
39
|
+
description: str = ""
|
|
40
|
+
label: Optional[str] = None
|
|
41
|
+
maturity: Optional[MaturityType] = None
|
|
42
|
+
meta: Dict[str, Any] = field(default_factory=dict)
|
|
43
|
+
tags: List[str] = field(default_factory=list)
|
|
44
|
+
config: ExposureConfig = field(default_factory=ExposureConfig)
|
|
45
|
+
unrendered_config: Dict[str, Any] = field(default_factory=dict)
|
|
46
|
+
url: Optional[str] = None
|
|
47
|
+
depends_on: DependsOn = field(default_factory=DependsOn)
|
|
48
|
+
refs: List[RefArgs] = field(default_factory=list)
|
|
49
|
+
sources: List[List[str]] = field(default_factory=list)
|
|
50
|
+
metrics: List[List[str]] = field(default_factory=list)
|
|
51
|
+
created_at: float = field(default_factory=lambda: time.time())
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
from typing import List, Literal, Optional
|
|
3
|
+
|
|
4
|
+
from dbt.artifacts.resources.types import FunctionType, FunctionVolatility, NodeType
|
|
5
|
+
from dbt.artifacts.resources.v1.components import CompiledResource
|
|
6
|
+
from dbt.artifacts.resources.v1.config import NodeConfig
|
|
7
|
+
from dbt_common.dataclass_schema import dbtClassMixin
|
|
8
|
+
|
|
9
|
+
# =============
|
|
10
|
+
# Function config, and supporting classes
|
|
11
|
+
# =============
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass
|
|
15
|
+
class FunctionConfig(NodeConfig):
|
|
16
|
+
# The fact that this is a property, that can be changed, seems wrong.
|
|
17
|
+
# A function's materialization should never be changed, so why allow for it?
|
|
18
|
+
materialized: str = "function"
|
|
19
|
+
type: FunctionType = FunctionType.Scalar
|
|
20
|
+
volatility: Optional[FunctionVolatility] = None
|
|
21
|
+
runtime_version: Optional[str] = None
|
|
22
|
+
entry_point: Optional[str] = None
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# =============
|
|
26
|
+
# Function resource, and supporting classes
|
|
27
|
+
# =============
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass
|
|
31
|
+
class FunctionArgument(dbtClassMixin):
|
|
32
|
+
name: str
|
|
33
|
+
data_type: str
|
|
34
|
+
description: Optional[str] = None
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@dataclass
|
|
38
|
+
class FunctionReturns(dbtClassMixin):
|
|
39
|
+
data_type: str
|
|
40
|
+
description: Optional[str] = None
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@dataclass
|
|
44
|
+
class FunctionMandatory(dbtClassMixin):
|
|
45
|
+
returns: FunctionReturns
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@dataclass
|
|
49
|
+
class Function(CompiledResource, FunctionMandatory):
|
|
50
|
+
resource_type: Literal[NodeType.Function]
|
|
51
|
+
config: FunctionConfig
|
|
52
|
+
arguments: List[FunctionArgument] = field(default_factory=list)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
from typing import Any, Dict, Literal, Optional
|
|
3
|
+
|
|
4
|
+
from dbt.artifacts.resources.types import NodeType
|
|
5
|
+
from dbt.artifacts.resources.v1.components import CompiledResource
|
|
6
|
+
from dbt.artifacts.resources.v1.config import TestConfig
|
|
7
|
+
from dbt_common.dataclass_schema import dbtClassMixin
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass
|
|
11
|
+
class TestMetadata(dbtClassMixin):
|
|
12
|
+
__test__ = False
|
|
13
|
+
|
|
14
|
+
name: str = "test" # dummy default to allow default in GenericTestNode. Should always be set.
|
|
15
|
+
# kwargs are the args that are left in the test builder after
|
|
16
|
+
# removing configs. They are set from the test builder when
|
|
17
|
+
# the test node is created.
|
|
18
|
+
kwargs: Dict[str, Any] = field(default_factory=dict)
|
|
19
|
+
namespace: Optional[str] = None
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass
|
|
23
|
+
class GenericTest(CompiledResource):
|
|
24
|
+
resource_type: Literal[NodeType.Test]
|
|
25
|
+
column_name: Optional[str] = None
|
|
26
|
+
file_key_name: Optional[str] = None
|
|
27
|
+
# Was not able to make mypy happy and keep the code working. We need to
|
|
28
|
+
# refactor the various configs.
|
|
29
|
+
config: TestConfig = field(default_factory=TestConfig) # type: ignore
|
|
30
|
+
attached_node: Optional[str] = None
|
|
31
|
+
test_metadata: TestMetadata = field(default_factory=TestMetadata)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
from typing import Any, Dict, Literal, Optional
|
|
3
|
+
|
|
4
|
+
from dbt.artifacts.resources.base import BaseResource
|
|
5
|
+
from dbt.artifacts.resources.types import NodeType
|
|
6
|
+
from dbt.artifacts.resources.v1.owner import Owner
|
|
7
|
+
from dbt_common.contracts.config.base import BaseConfig, MergeBehavior
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass
|
|
11
|
+
class GroupConfig(BaseConfig):
|
|
12
|
+
meta: Dict[str, Any] = field(default_factory=dict, metadata=MergeBehavior.Update.meta())
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass
|
|
16
|
+
class Group(BaseResource):
|
|
17
|
+
name: str
|
|
18
|
+
owner: Owner
|
|
19
|
+
resource_type: Literal[NodeType.Group]
|
|
20
|
+
description: Optional[str] = None
|
|
21
|
+
config: GroupConfig = field(default_factory=GroupConfig)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Literal, Optional
|
|
3
|
+
|
|
4
|
+
from dbt.artifacts.resources.types import NodeType
|
|
5
|
+
from dbt.artifacts.resources.v1.components import CompiledResource
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass
|
|
9
|
+
class HookNode(CompiledResource):
|
|
10
|
+
resource_type: Literal[NodeType.Operation]
|
|
11
|
+
index: Optional[int] = None
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import time
|
|
2
|
+
from dataclasses import dataclass, field
|
|
3
|
+
from typing import Any, Dict, List, Literal, Optional
|
|
4
|
+
|
|
5
|
+
from dbt.artifacts.resources.base import BaseResource, Docs
|
|
6
|
+
from dbt.artifacts.resources.types import ModelLanguage, NodeType
|
|
7
|
+
from dbt.artifacts.resources.v1.components import MacroDependsOn
|
|
8
|
+
from dbt_common.dataclass_schema import dbtClassMixin
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class MacroArgument(dbtClassMixin):
|
|
13
|
+
name: str
|
|
14
|
+
type: Optional[str] = None
|
|
15
|
+
description: str = ""
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass
|
|
19
|
+
class Macro(BaseResource):
|
|
20
|
+
macro_sql: str
|
|
21
|
+
resource_type: Literal[NodeType.Macro]
|
|
22
|
+
depends_on: MacroDependsOn = field(default_factory=MacroDependsOn)
|
|
23
|
+
description: str = ""
|
|
24
|
+
meta: Dict[str, Any] = field(default_factory=dict)
|
|
25
|
+
docs: Docs = field(default_factory=Docs)
|
|
26
|
+
patch_path: Optional[str] = None
|
|
27
|
+
arguments: List[MacroArgument] = field(default_factory=list)
|
|
28
|
+
created_at: float = field(default_factory=lambda: time.time())
|
|
29
|
+
supported_languages: Optional[List[ModelLanguage]] = None
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import time
|
|
2
|
+
from dataclasses import dataclass, field
|
|
3
|
+
from typing import Any, Dict, List, Literal, Optional
|
|
4
|
+
|
|
5
|
+
from dbt.artifacts.resources.base import GraphResource
|
|
6
|
+
from dbt.artifacts.resources.types import NodeType
|
|
7
|
+
from dbt.artifacts.resources.v1.components import DependsOn, RefArgs
|
|
8
|
+
from dbt.artifacts.resources.v1.semantic_layer_components import (
|
|
9
|
+
MeasureAggregationParameters,
|
|
10
|
+
NonAdditiveDimension,
|
|
11
|
+
SourceFileMetadata,
|
|
12
|
+
WhereFilterIntersection,
|
|
13
|
+
)
|
|
14
|
+
from dbt_common.contracts.config.base import BaseConfig, CompareBehavior, MergeBehavior
|
|
15
|
+
from dbt_common.dataclass_schema import dbtClassMixin
|
|
16
|
+
from dbt_semantic_interfaces.references import MeasureReference, MetricReference
|
|
17
|
+
from dbt_semantic_interfaces.type_enums import (
|
|
18
|
+
AggregationType,
|
|
19
|
+
ConversionCalculationType,
|
|
20
|
+
MetricType,
|
|
21
|
+
PeriodAggregation,
|
|
22
|
+
TimeGranularity,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
"""
|
|
26
|
+
The following classes are dataclasses which are used to construct the Metric
|
|
27
|
+
node in dbt-core. Additionally, these classes need to at a minimum support
|
|
28
|
+
what is specified in their protocol definitions in dbt-semantic-interfaces.
|
|
29
|
+
Their protocol definitions can be found here:
|
|
30
|
+
https://github.com/dbt-labs/dbt-semantic-interfaces/blob/main/dbt_semantic_interfaces/protocols/metric.py
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@dataclass
|
|
35
|
+
class MetricInputMeasure(dbtClassMixin):
|
|
36
|
+
name: str
|
|
37
|
+
filter: Optional[WhereFilterIntersection] = None
|
|
38
|
+
alias: Optional[str] = None
|
|
39
|
+
join_to_timespine: bool = False
|
|
40
|
+
fill_nulls_with: Optional[int] = None
|
|
41
|
+
|
|
42
|
+
def measure_reference(self) -> MeasureReference:
|
|
43
|
+
return MeasureReference(element_name=self.name)
|
|
44
|
+
|
|
45
|
+
def post_aggregation_measure_reference(self) -> MeasureReference:
|
|
46
|
+
return MeasureReference(element_name=self.alias or self.name)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@dataclass
|
|
50
|
+
class MetricTimeWindow(dbtClassMixin):
|
|
51
|
+
count: int
|
|
52
|
+
granularity: str
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def window_string(self) -> str: # noqa: D
|
|
56
|
+
return f"{self.count} {self.granularity}"
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def is_standard_granularity(self) -> bool: # noqa: D
|
|
60
|
+
return self.granularity.casefold() in {item.value.casefold() for item in TimeGranularity}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@dataclass
|
|
64
|
+
class MetricInput(dbtClassMixin):
|
|
65
|
+
name: str
|
|
66
|
+
filter: Optional[WhereFilterIntersection] = None
|
|
67
|
+
alias: Optional[str] = None
|
|
68
|
+
offset_window: Optional[MetricTimeWindow] = None
|
|
69
|
+
offset_to_grain: Optional[str] = None
|
|
70
|
+
|
|
71
|
+
def as_reference(self) -> MetricReference:
|
|
72
|
+
return MetricReference(element_name=self.name)
|
|
73
|
+
|
|
74
|
+
def post_aggregation_reference(self) -> MetricReference:
|
|
75
|
+
return MetricReference(element_name=self.alias or self.name)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@dataclass
|
|
79
|
+
class ConstantPropertyInput(dbtClassMixin):
|
|
80
|
+
base_property: str
|
|
81
|
+
conversion_property: str
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
@dataclass
|
|
85
|
+
class ConversionTypeParams(dbtClassMixin):
|
|
86
|
+
base_measure: MetricInputMeasure
|
|
87
|
+
conversion_measure: MetricInputMeasure
|
|
88
|
+
entity: str
|
|
89
|
+
calculation: ConversionCalculationType = ConversionCalculationType.CONVERSION_RATE
|
|
90
|
+
window: Optional[MetricTimeWindow] = None
|
|
91
|
+
constant_properties: Optional[List[ConstantPropertyInput]] = None
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
@dataclass
|
|
95
|
+
class CumulativeTypeParams(dbtClassMixin):
|
|
96
|
+
window: Optional[MetricTimeWindow] = None
|
|
97
|
+
grain_to_date: Optional[str] = None
|
|
98
|
+
period_agg: PeriodAggregation = PeriodAggregation.FIRST
|
|
99
|
+
metric: Optional[MetricInput] = None
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@dataclass
|
|
103
|
+
class MetricAggregationParams(dbtClassMixin):
|
|
104
|
+
semantic_model: str
|
|
105
|
+
agg: AggregationType
|
|
106
|
+
agg_params: Optional[MeasureAggregationParameters] = None
|
|
107
|
+
agg_time_dimension: Optional[str] = None
|
|
108
|
+
non_additive_dimension: Optional[NonAdditiveDimension] = None
|
|
109
|
+
expr: Optional[str] = None
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
@dataclass
|
|
113
|
+
class MetricTypeParams(dbtClassMixin):
|
|
114
|
+
measure: Optional[MetricInputMeasure] = None
|
|
115
|
+
input_measures: List[MetricInputMeasure] = field(default_factory=list)
|
|
116
|
+
numerator: Optional[MetricInput] = None
|
|
117
|
+
denominator: Optional[MetricInput] = None
|
|
118
|
+
expr: Optional[str] = None
|
|
119
|
+
window: Optional[MetricTimeWindow] = None
|
|
120
|
+
grain_to_date: Optional[TimeGranularity] = (
|
|
121
|
+
None # legacy, use cumulative_type_params.grain_to_date
|
|
122
|
+
)
|
|
123
|
+
metrics: Optional[List[MetricInput]] = None
|
|
124
|
+
conversion_type_params: Optional[ConversionTypeParams] = None
|
|
125
|
+
cumulative_type_params: Optional[CumulativeTypeParams] = None
|
|
126
|
+
metric_aggregation_params: Optional[MetricAggregationParams] = None
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
@dataclass
|
|
130
|
+
class MetricConfig(BaseConfig):
|
|
131
|
+
enabled: bool = True
|
|
132
|
+
group: Optional[str] = field(
|
|
133
|
+
default=None,
|
|
134
|
+
metadata=CompareBehavior.Exclude.meta(),
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
meta: Dict[str, Any] = field(default_factory=dict, metadata=MergeBehavior.Update.meta())
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
@dataclass
|
|
141
|
+
class Metric(GraphResource):
|
|
142
|
+
name: str
|
|
143
|
+
description: str
|
|
144
|
+
label: str
|
|
145
|
+
type: MetricType
|
|
146
|
+
type_params: MetricTypeParams
|
|
147
|
+
filter: Optional[WhereFilterIntersection] = None
|
|
148
|
+
metadata: Optional[SourceFileMetadata] = None
|
|
149
|
+
time_granularity: Optional[str] = None
|
|
150
|
+
resource_type: Literal[NodeType.Metric]
|
|
151
|
+
meta: Dict[str, Any] = field(default_factory=dict, metadata=MergeBehavior.Update.meta())
|
|
152
|
+
tags: List[str] = field(default_factory=list)
|
|
153
|
+
config: MetricConfig = field(default_factory=MetricConfig)
|
|
154
|
+
unrendered_config: Dict[str, Any] = field(default_factory=dict)
|
|
155
|
+
sources: List[List[str]] = field(default_factory=list)
|
|
156
|
+
depends_on: DependsOn = field(default_factory=DependsOn)
|
|
157
|
+
refs: List[RefArgs] = field(default_factory=list)
|
|
158
|
+
metrics: List[List[str]] = field(default_factory=list)
|
|
159
|
+
created_at: float = field(default_factory=lambda: time.time())
|
|
160
|
+
group: Optional[str] = None
|
|
161
|
+
|
|
162
|
+
@property
|
|
163
|
+
def input_measures(self) -> List[MetricInputMeasure]:
|
|
164
|
+
return self.type_params.input_measures
|
|
165
|
+
|
|
166
|
+
@property
|
|
167
|
+
def measure_references(self) -> List[MeasureReference]:
|
|
168
|
+
return [x.measure_reference() for x in self.input_measures]
|
|
169
|
+
|
|
170
|
+
@property
|
|
171
|
+
def input_metrics(self) -> List[MetricInput]:
|
|
172
|
+
return self.type_params.metrics or []
|