dagster-dbt 0.23.3__py3-none-any.whl → 0.28.4__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.
- dagster_dbt/__init__.py +41 -140
- dagster_dbt/asset_decorator.py +49 -230
- dagster_dbt/asset_specs.py +65 -0
- dagster_dbt/asset_utils.py +655 -338
- dagster_dbt/cli/app.py +44 -43
- dagster_dbt/cloud/__init__.py +6 -4
- dagster_dbt/cloud/asset_defs.py +119 -177
- dagster_dbt/cloud/cli.py +3 -4
- dagster_dbt/cloud/ops.py +9 -6
- dagster_dbt/cloud/resources.py +9 -4
- dagster_dbt/cloud/types.py +12 -7
- dagster_dbt/cloud/utils.py +186 -0
- dagster_dbt/cloud_v2/__init__.py +10 -0
- dagster_dbt/cloud_v2/asset_decorator.py +81 -0
- dagster_dbt/cloud_v2/cli_invocation.py +67 -0
- dagster_dbt/cloud_v2/client.py +438 -0
- dagster_dbt/cloud_v2/resources.py +462 -0
- dagster_dbt/cloud_v2/run_handler.py +229 -0
- dagster_dbt/cloud_v2/sensor_builder.py +254 -0
- dagster_dbt/cloud_v2/types.py +143 -0
- dagster_dbt/compat.py +107 -0
- dagster_dbt/components/__init__.py +0 -0
- dagster_dbt/components/dbt_project/__init__.py +0 -0
- dagster_dbt/components/dbt_project/component.py +545 -0
- dagster_dbt/components/dbt_project/scaffolder.py +65 -0
- dagster_dbt/core/__init__.py +0 -10
- dagster_dbt/core/dbt_cli_event.py +612 -0
- dagster_dbt/core/dbt_cli_invocation.py +474 -0
- dagster_dbt/core/dbt_event_iterator.py +399 -0
- dagster_dbt/core/resource.py +733 -0
- dagster_dbt/core/utils.py +14 -279
- dagster_dbt/dagster_dbt_translator.py +317 -74
- dagster_dbt/dbt_core_version.py +1 -0
- dagster_dbt/dbt_manifest.py +6 -5
- dagster_dbt/dbt_manifest_asset_selection.py +62 -22
- dagster_dbt/dbt_project.py +179 -40
- dagster_dbt/dbt_project_manager.py +173 -0
- dagster_dbt/dbt_version.py +0 -0
- dagster_dbt/errors.py +9 -84
- dagster_dbt/freshness_builder.py +147 -0
- dagster_dbt/include/pyproject.toml.jinja +21 -0
- dagster_dbt/include/scaffold/assets.py.jinja +1 -8
- dagster_dbt/include/scaffold/definitions.py.jinja +0 -15
- dagster_dbt/include/scaffold/project.py.jinja +1 -0
- dagster_dbt/include/setup.py.jinja +2 -3
- dagster_dbt/metadata_set.py +18 -0
- dagster_dbt/utils.py +136 -234
- dagster_dbt/version.py +1 -1
- dagster_dbt-0.28.4.dist-info/METADATA +47 -0
- dagster_dbt-0.28.4.dist-info/RECORD +59 -0
- {dagster_dbt-0.23.3.dist-info → dagster_dbt-0.28.4.dist-info}/WHEEL +1 -1
- {dagster_dbt-0.23.3.dist-info → dagster_dbt-0.28.4.dist-info}/entry_points.txt +3 -0
- {dagster_dbt-0.23.3.dist-info → dagster_dbt-0.28.4.dist-info/licenses}/LICENSE +1 -1
- dagster_dbt/asset_defs.py +0 -1049
- dagster_dbt/core/resources.py +0 -527
- dagster_dbt/core/resources_v2.py +0 -1542
- dagster_dbt/core/types.py +0 -63
- dagster_dbt/dbt_resource.py +0 -220
- dagster_dbt/include/scaffold/constants.py.jinja +0 -21
- dagster_dbt/ops.py +0 -134
- dagster_dbt/types.py +0 -22
- dagster_dbt-0.23.3.dist-info/METADATA +0 -31
- dagster_dbt-0.23.3.dist-info/RECORD +0 -43
- {dagster_dbt-0.23.3.dist-info → dagster_dbt-0.28.4.dist-info}/top_level.txt +0 -0
dagster_dbt/errors.py
CHANGED
|
@@ -1,98 +1,15 @@
|
|
|
1
|
-
import warnings
|
|
2
1
|
from abc import ABC
|
|
3
|
-
from typing import Any, Mapping, Optional, Sequence
|
|
4
2
|
|
|
5
|
-
from dagster import
|
|
6
|
-
DagsterInvariantViolationError,
|
|
7
|
-
Failure,
|
|
8
|
-
MetadataValue,
|
|
9
|
-
_check as check,
|
|
10
|
-
)
|
|
3
|
+
from dagster import DagsterInvariantViolationError, Failure
|
|
11
4
|
|
|
12
5
|
|
|
13
6
|
class DagsterDbtError(Failure, ABC):
|
|
14
7
|
"""The base exception of the ``dagster-dbt`` library."""
|
|
15
8
|
|
|
16
9
|
|
|
17
|
-
class DagsterDbtCliUnexpectedOutputError(DagsterDbtError):
|
|
18
|
-
"""Represents an error when parsing the output of a dbt CLI command."""
|
|
19
|
-
|
|
20
|
-
invalid_line_nos: Sequence[int]
|
|
21
|
-
|
|
22
|
-
def __init__(self, invalid_line_nos: Sequence[int]):
|
|
23
|
-
check.sequence_param(invalid_line_nos, "invalid_line_nos", int)
|
|
24
|
-
line_nos_str = ", ".join(map(str, invalid_line_nos))
|
|
25
|
-
description = f"dbt CLI emitted unexpected output on lines {line_nos_str}"
|
|
26
|
-
metadata = {
|
|
27
|
-
"Invalid CLI Output Line Numbers": MetadataValue.json({"line_nos": invalid_line_nos})
|
|
28
|
-
}
|
|
29
|
-
super().__init__(description, metadata=metadata)
|
|
30
|
-
self.invalid_line_nos = invalid_line_nos
|
|
31
|
-
|
|
32
|
-
|
|
33
10
|
class DagsterDbtCliRuntimeError(DagsterDbtError, ABC):
|
|
34
11
|
"""Represents an error while executing a dbt CLI command."""
|
|
35
12
|
|
|
36
|
-
def __init__(
|
|
37
|
-
self,
|
|
38
|
-
description: str,
|
|
39
|
-
logs: Optional[Sequence[Mapping[str, Any]]] = None,
|
|
40
|
-
raw_output: Optional[str] = None,
|
|
41
|
-
messages: Optional[Sequence[str]] = None,
|
|
42
|
-
):
|
|
43
|
-
if logs is not None:
|
|
44
|
-
warnings.warn(
|
|
45
|
-
"`logs` is a deprecated argument to DagsterDbtCliRuntimeError and will be discarded"
|
|
46
|
-
)
|
|
47
|
-
if raw_output is not None:
|
|
48
|
-
warnings.warn(
|
|
49
|
-
"`raw_output` is a deprecated argument to DagsterDbtCliRuntimeError and will be"
|
|
50
|
-
" discarded"
|
|
51
|
-
)
|
|
52
|
-
metadata = {"Parsed CLI Messages": "\n".join(messages or [])}
|
|
53
|
-
super().__init__(description, metadata=metadata)
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
class DagsterDbtCliHandledRuntimeError(DagsterDbtCliRuntimeError):
|
|
57
|
-
"""Represents a model error reported by the dbt CLI at runtime (return code 1)."""
|
|
58
|
-
|
|
59
|
-
def __init__(
|
|
60
|
-
self,
|
|
61
|
-
logs: Optional[Sequence[Mapping[str, Any]]] = None,
|
|
62
|
-
raw_output: Optional[str] = None,
|
|
63
|
-
messages: Optional[Sequence[str]] = None,
|
|
64
|
-
):
|
|
65
|
-
super().__init__("Handled error in the dbt CLI (return code 1)", logs, raw_output, messages)
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
class DagsterDbtCliFatalRuntimeError(DagsterDbtCliRuntimeError):
|
|
69
|
-
"""Represents a fatal error in the dbt CLI (return code 2)."""
|
|
70
|
-
|
|
71
|
-
def __init__(
|
|
72
|
-
self,
|
|
73
|
-
logs: Optional[Sequence[Mapping[str, Any]]] = None,
|
|
74
|
-
raw_output: Optional[str] = None,
|
|
75
|
-
messages: Optional[Sequence[str]] = None,
|
|
76
|
-
):
|
|
77
|
-
super().__init__(
|
|
78
|
-
"Fatal error in the dbt CLI (return code 2): " + " ".join(messages or []),
|
|
79
|
-
logs,
|
|
80
|
-
raw_output,
|
|
81
|
-
messages,
|
|
82
|
-
)
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
class DagsterDbtCliOutputsNotFoundError(DagsterDbtError):
|
|
86
|
-
"""Represents a problem in finding the ``target/run_results.json`` artifact when executing a dbt
|
|
87
|
-
CLI command.
|
|
88
|
-
|
|
89
|
-
For more details on ``target/run_results.json``, see
|
|
90
|
-
https://docs.getdbt.com/reference/dbt-artifacts#run_resultsjson.
|
|
91
|
-
"""
|
|
92
|
-
|
|
93
|
-
def __init__(self, path: str):
|
|
94
|
-
super().__init__(f"Expected to find file at path {path}")
|
|
95
|
-
|
|
96
13
|
|
|
97
14
|
class DagsterDbtCloudJobInvariantViolationError(DagsterDbtError, DagsterInvariantViolationError):
|
|
98
15
|
"""Represents an error when a dbt Cloud job is not supported by the ``dagster-dbt`` library."""
|
|
@@ -102,5 +19,13 @@ class DagsterDbtProjectNotFoundError(DagsterDbtError):
|
|
|
102
19
|
"""Error when the specified project directory can not be found."""
|
|
103
20
|
|
|
104
21
|
|
|
22
|
+
class DagsterDbtProfilesDirectoryNotFoundError(DagsterDbtError):
|
|
23
|
+
"""Error when the specified profiles directory can not be found."""
|
|
24
|
+
|
|
25
|
+
|
|
105
26
|
class DagsterDbtManifestNotFoundError(DagsterDbtError):
|
|
106
27
|
"""Error when we expect manifest.json to generated already but it is absent."""
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class DagsterDbtProjectYmlFileNotFoundError(DagsterDbtError):
|
|
31
|
+
"""Error when a dbt_project.yml file can not be found in the specified project directory."""
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import datetime
|
|
2
|
+
from collections.abc import Mapping, Sequence
|
|
3
|
+
from typing import TYPE_CHECKING, Any
|
|
4
|
+
|
|
5
|
+
from dagster import (
|
|
6
|
+
AssetsDefinition,
|
|
7
|
+
_check as check,
|
|
8
|
+
)
|
|
9
|
+
from dagster._core.definitions.asset_checks.asset_check_factories.freshness_checks.last_update import (
|
|
10
|
+
build_last_update_freshness_checks,
|
|
11
|
+
)
|
|
12
|
+
from dagster._core.definitions.asset_checks.asset_check_factories.freshness_checks.time_partition import (
|
|
13
|
+
build_time_partition_freshness_checks,
|
|
14
|
+
)
|
|
15
|
+
from dagster._core.definitions.asset_checks.asset_check_factories.utils import (
|
|
16
|
+
DEFAULT_FRESHNESS_SEVERITY,
|
|
17
|
+
asset_to_keys_iterable,
|
|
18
|
+
assets_to_keys,
|
|
19
|
+
ensure_no_duplicate_assets,
|
|
20
|
+
)
|
|
21
|
+
from dagster._core.definitions.asset_checks.asset_check_spec import AssetCheckSeverity
|
|
22
|
+
from dagster._core.definitions.asset_checks.asset_checks_definition import AssetChecksDefinition
|
|
23
|
+
from dagster._core.definitions.partitions.definition import TimeWindowPartitionsDefinition
|
|
24
|
+
from dagster._core.errors import DagsterInvariantViolationError
|
|
25
|
+
|
|
26
|
+
if TYPE_CHECKING:
|
|
27
|
+
from dagster import AssetKey
|
|
28
|
+
|
|
29
|
+
from dagster._symbol_annotations.lifecycle import superseded
|
|
30
|
+
|
|
31
|
+
from dagster_dbt.asset_utils import (
|
|
32
|
+
get_asset_keys_to_resource_props,
|
|
33
|
+
get_manifest_and_translator_from_dbt_assets,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@superseded(
|
|
38
|
+
additional_warn_text="Create `FreshnessPolicy` objects for your dbt models by overriding `get_asset_spec` "
|
|
39
|
+
"in your `DagsterDbtTranslator`, or by updating the `translation` configuration of your `DbtProjectComponent` instead."
|
|
40
|
+
)
|
|
41
|
+
def build_freshness_checks_from_dbt_assets(
|
|
42
|
+
*,
|
|
43
|
+
dbt_assets: Sequence[AssetsDefinition],
|
|
44
|
+
) -> Sequence[AssetChecksDefinition]:
|
|
45
|
+
"""Returns a sequence of freshness checks constructed from the provided dbt assets.
|
|
46
|
+
|
|
47
|
+
Freshness checks can be configured on a per-model basis in the model schema configuration.
|
|
48
|
+
|
|
49
|
+
For assets which are not partitioned based on time, the freshness check configuration mirrors
|
|
50
|
+
that of the :py:func:`build_last_update_freshness_checks` function. `lower_bound_delta` is provided in
|
|
51
|
+
terms of seconds, and `deadline_cron` is optional.
|
|
52
|
+
|
|
53
|
+
For time-partitioned assets, the freshness check configuration mirrors that of the
|
|
54
|
+
:py:func:`build_time_partition_freshness_checks` function.
|
|
55
|
+
|
|
56
|
+
Below is example of configuring a non-time-partitioned dbt asset with a freshness check.
|
|
57
|
+
This code would be placed in the schema.yml file for the dbt model.
|
|
58
|
+
|
|
59
|
+
.. code-block:: YAML
|
|
60
|
+
|
|
61
|
+
models:
|
|
62
|
+
- name: customers
|
|
63
|
+
...
|
|
64
|
+
meta:
|
|
65
|
+
dagster:
|
|
66
|
+
freshness_check:
|
|
67
|
+
lower_bound_delta_seconds: 86400 # 1 day
|
|
68
|
+
deadline_cron: "0 0 * * *" # Optional
|
|
69
|
+
severity: "WARN" # Optional, defaults to "WARN"
|
|
70
|
+
|
|
71
|
+
Below is an example of configuring a time-partitioned dbt asset with a freshness check.
|
|
72
|
+
This code would be placed in the schema.yml file for the dbt model.
|
|
73
|
+
|
|
74
|
+
.. code-block:: yaml
|
|
75
|
+
|
|
76
|
+
models:
|
|
77
|
+
- name: customers
|
|
78
|
+
...
|
|
79
|
+
meta:
|
|
80
|
+
dagster:
|
|
81
|
+
freshness_check:
|
|
82
|
+
deadline_cron: "0 0 * * *"
|
|
83
|
+
severity: "WARN" # Optional, defaults to "WARN"
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
dbt_assets (Sequence[AssetsDefinition]): A sequence of dbt assets to construct freshness
|
|
87
|
+
checks from.
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
Sequence[AssetChecksDefinition]: A sequence of asset checks definitions representing the
|
|
91
|
+
freshness checks for the provided dbt assets.
|
|
92
|
+
"""
|
|
93
|
+
freshness_checks = []
|
|
94
|
+
dbt_assets = check.sequence_param(dbt_assets, "dbt_assets", AssetsDefinition)
|
|
95
|
+
ensure_no_duplicate_assets(dbt_assets)
|
|
96
|
+
asset_key_to_assets_def: dict[AssetKey, AssetsDefinition] = {}
|
|
97
|
+
asset_key_to_resource_props: Mapping[AssetKey, Mapping[str, Any]] = {}
|
|
98
|
+
for assets_def in dbt_assets:
|
|
99
|
+
manifest, translator, _ = get_manifest_and_translator_from_dbt_assets([assets_def])
|
|
100
|
+
asset_key_to_resource_props_for_def = get_asset_keys_to_resource_props(manifest, translator)
|
|
101
|
+
for asset_key in asset_to_keys_iterable(assets_def):
|
|
102
|
+
if asset_key not in asset_key_to_resource_props_for_def:
|
|
103
|
+
raise DagsterInvariantViolationError(
|
|
104
|
+
f"Could not find dbt resource properties for asset key {asset_key.to_user_string()}."
|
|
105
|
+
)
|
|
106
|
+
asset_key_to_assets_def[asset_key] = assets_def
|
|
107
|
+
asset_key_to_resource_props[asset_key] = asset_key_to_resource_props_for_def[asset_key]
|
|
108
|
+
for asset_key in assets_to_keys(dbt_assets):
|
|
109
|
+
dbt_resource_props = asset_key_to_resource_props[asset_key]
|
|
110
|
+
assets_def = asset_key_to_assets_def[asset_key]
|
|
111
|
+
dagster_metadata = dbt_resource_props.get("meta", {}).get("dagster", {})
|
|
112
|
+
freshness_check_config = dagster_metadata.get("freshness_check", {})
|
|
113
|
+
if not freshness_check_config:
|
|
114
|
+
continue
|
|
115
|
+
|
|
116
|
+
severity_str = freshness_check_config.get("severity")
|
|
117
|
+
severity = AssetCheckSeverity(severity_str) if severity_str else DEFAULT_FRESHNESS_SEVERITY
|
|
118
|
+
if assets_def.partitions_def and isinstance(
|
|
119
|
+
assets_def.partitions_def, TimeWindowPartitionsDefinition
|
|
120
|
+
):
|
|
121
|
+
freshness_checks.extend(
|
|
122
|
+
build_time_partition_freshness_checks(
|
|
123
|
+
assets=[asset_key],
|
|
124
|
+
deadline_cron=freshness_check_config.get("deadline_cron"),
|
|
125
|
+
severity=severity,
|
|
126
|
+
)
|
|
127
|
+
)
|
|
128
|
+
else:
|
|
129
|
+
try:
|
|
130
|
+
lower_bound_delta_seconds_str = freshness_check_config["lower_bound_delta_seconds"]
|
|
131
|
+
lower_bound_seconds = int(lower_bound_delta_seconds_str)
|
|
132
|
+
except:
|
|
133
|
+
raise DagsterInvariantViolationError(
|
|
134
|
+
"lower_bound_delta_seconds must be provided, and parseable as an integer "
|
|
135
|
+
"in the freshness_check config for a non-time-partitioned asset."
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
freshness_checks.extend(
|
|
139
|
+
build_last_update_freshness_checks(
|
|
140
|
+
assets=[translator.get_asset_key(dbt_resource_props)], # pyright: ignore[reportPossiblyUnboundVariable]
|
|
141
|
+
deadline_cron=freshness_check_config.get("deadline_cron"),
|
|
142
|
+
lower_bound_delta=datetime.timedelta(seconds=lower_bound_seconds),
|
|
143
|
+
severity=severity,
|
|
144
|
+
)
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
return freshness_checks
|
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "{{ project_name }}"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Add your description here"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.10,<3.14"
|
|
7
|
+
dependencies = [
|
|
8
|
+
"dagster",
|
|
9
|
+
"dagster-cloud",
|
|
10
|
+
"dagster-dbt",
|
|
11
|
+
"dbt-core<{{ dbt_core_version_upper_bound }}",
|
|
12
|
+
{%- for dbt_adapter in dbt_adapter_packages %}
|
|
13
|
+
"{{ dbt_adapter }}<{{ dbt_core_version_upper_bound }}",
|
|
14
|
+
{%- endfor %}
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
[project.optional-dependencies]
|
|
18
|
+
dev = [
|
|
19
|
+
"dagster-webserver",
|
|
20
|
+
]
|
|
21
|
+
|
|
1
22
|
[build-system]
|
|
2
23
|
requires = ["setuptools"]
|
|
3
24
|
build-backend = "setuptools.build_meta"
|
|
@@ -1,17 +1,10 @@
|
|
|
1
1
|
from dagster import AssetExecutionContext
|
|
2
2
|
from dagster_dbt import DbtCliResource, dbt_assets
|
|
3
3
|
|
|
4
|
-
{% if use_experimental_dbt_project -%}
|
|
5
4
|
from .project import {{ dbt_project_name }}
|
|
6
|
-
{% else -%}
|
|
7
|
-
from .constants import dbt_manifest_path
|
|
8
|
-
{% endif %}
|
|
9
5
|
|
|
10
|
-
|
|
6
|
+
|
|
11
7
|
@dbt_assets(manifest={{ dbt_project_name }}.manifest_path)
|
|
12
|
-
{% else -%}
|
|
13
|
-
@dbt_assets(manifest=dbt_manifest_path)
|
|
14
|
-
{% endif -%}
|
|
15
8
|
def {{ dbt_assets_name }}(context: AssetExecutionContext, dbt: DbtCliResource):
|
|
16
9
|
{% if use_experimental_dbt_state -%}
|
|
17
10
|
# When dbt state is available, pass it to the dbt invocation.
|
|
@@ -1,28 +1,13 @@
|
|
|
1
|
-
{% if use_experimental_dbt_project -%}
|
|
2
1
|
from dagster import Definitions
|
|
3
2
|
from dagster_dbt import DbtCliResource
|
|
4
|
-
{% else -%}
|
|
5
|
-
import os
|
|
6
|
-
|
|
7
|
-
from dagster import Definitions
|
|
8
|
-
from dagster_dbt import DbtCliResource
|
|
9
|
-
{% endif %}
|
|
10
3
|
from .assets import {{ dbt_assets_name }}
|
|
11
|
-
{% if use_experimental_dbt_project -%}
|
|
12
4
|
from .project import {{ dbt_project_name }}
|
|
13
|
-
{% else -%}
|
|
14
|
-
from .constants import dbt_project_dir
|
|
15
|
-
{% endif -%}
|
|
16
5
|
from .schedules import schedules
|
|
17
6
|
|
|
18
7
|
defs = Definitions(
|
|
19
8
|
assets=[{{ dbt_assets_name }}],
|
|
20
9
|
schedules=schedules,
|
|
21
10
|
resources={
|
|
22
|
-
{% if use_experimental_dbt_project -%}
|
|
23
11
|
"dbt": DbtCliResource(project_dir={{ dbt_project_name }}),
|
|
24
|
-
{%- else -%}
|
|
25
|
-
"dbt": DbtCliResource(project_dir=os.fspath(dbt_project_dir)),
|
|
26
|
-
{%- endif %}
|
|
27
12
|
},
|
|
28
13
|
)
|
|
@@ -4,19 +4,18 @@ setup(
|
|
|
4
4
|
name="{{ project_name }}",
|
|
5
5
|
version="0.0.1",
|
|
6
6
|
packages=find_packages(),
|
|
7
|
-
{%- if use_experimental_dbt_project %}
|
|
8
7
|
package_data={
|
|
9
8
|
"{{ project_name }}": [
|
|
10
9
|
"dbt-project/**/*",
|
|
11
10
|
],
|
|
12
11
|
},
|
|
13
|
-
{%- endif %}
|
|
14
12
|
install_requires=[
|
|
15
13
|
"dagster",
|
|
16
14
|
"dagster-cloud",
|
|
17
15
|
"dagster-dbt",
|
|
16
|
+
"dbt-core<{{ dbt_core_version_upper_bound }}",
|
|
18
17
|
{%- for dbt_adapter in dbt_adapter_packages %}
|
|
19
|
-
"{{ dbt_adapter }}",
|
|
18
|
+
"{{ dbt_adapter }}<{{ dbt_core_version_upper_bound }}",
|
|
20
19
|
{%- endfor %}
|
|
21
20
|
],
|
|
22
21
|
extras_require={
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from dagster._core.definitions.metadata.metadata_set import NamespacedMetadataSet
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class DbtMetadataSet(NamespacedMetadataSet):
|
|
7
|
+
"""Metadata entries that apply to dbt objects.
|
|
8
|
+
|
|
9
|
+
Args:
|
|
10
|
+
materialization_type (Optional[str]): The materialization type, like "table" or "view". See
|
|
11
|
+
https://docs.getdbt.com/docs/build/materializations.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
materialization_type: Optional[str]
|
|
15
|
+
|
|
16
|
+
@classmethod
|
|
17
|
+
def namespace(cls) -> str:
|
|
18
|
+
return "dagster-dbt"
|