dagster-dbt 0.27.14__py3-none-any.whl → 0.27.16__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.
@@ -1,6 +1,9 @@
1
1
  import itertools
2
2
  import json
3
+ import shutil
3
4
  from collections.abc import Iterator, Mapping
5
+ from contextlib import contextmanager
6
+ from contextvars import ContextVar
4
7
  from dataclasses import dataclass, field
5
8
  from functools import cached_property
6
9
  from pathlib import Path
@@ -9,10 +12,12 @@ from typing import Annotated, Any, Literal, Optional, Union
9
12
  import dagster as dg
10
13
  from dagster._annotations import public
11
14
  from dagster._utils.cached_method import cached_method
15
+ from dagster.components.component.state_backed_component import StateBackedComponent
12
16
  from dagster.components.core.component_tree import ComponentTree
13
17
  from dagster.components.resolved.core_models import OpSpec, ResolutionContext
14
18
  from dagster.components.resolved.model import Resolver
15
19
  from dagster.components.scaffold.scaffold import scaffold_with
20
+ from dagster.components.utils.defs_state import DefsStateConfig
16
21
  from dagster.components.utils.translation import (
17
22
  ComponentTranslator,
18
23
  TranslationFn,
@@ -20,6 +25,7 @@ from dagster.components.utils.translation import (
20
25
  create_component_translator_cls,
21
26
  )
22
27
  from dagster_shared import check
28
+ from dagster_shared.serdes.objects.models.defs_state_info import DefsStateManagementType
23
29
  from typing_extensions import TypeAlias
24
30
 
25
31
  from dagster_dbt.asset_decorator import dbt_assets
@@ -84,11 +90,22 @@ def resolve_dbt_project(context: ResolutionContext, model) -> DbtProject:
84
90
 
85
91
  DbtMetadataAddons: TypeAlias = Literal["column_metadata", "row_count"]
86
92
 
93
+ _resolution_context: ContextVar[ResolutionContext] = ContextVar("resolution_context")
94
+
95
+
96
+ @contextmanager
97
+ def _set_resolution_context(context: ResolutionContext):
98
+ token = _resolution_context.set(context)
99
+ try:
100
+ yield
101
+ finally:
102
+ _resolution_context.reset(token)
103
+
87
104
 
88
105
  @public
89
106
  @scaffold_with(DbtProjectComponentScaffolder)
90
107
  @dataclass
91
- class DbtProjectComponent(dg.Component, dg.Resolvable):
108
+ class DbtProjectComponent(StateBackedComponent, dg.Resolvable):
92
109
  """Expose a DBT project to Dagster as a set of assets.
93
110
 
94
111
  This component assumes that you have already set up a dbt project, for example, the dbt `Jaffle shop <https://github.com/dbt-labs/jaffle-shop>`_. Run `git clone --depth=1 https://github.com/dbt-labs/jaffle-shop.git jaffle_shop && rm -rf jaffle_shop/.git` to copy that project
@@ -125,8 +142,8 @@ class DbtProjectComponent(dg.Component, dg.Resolvable):
125
142
  "--full_refresh",
126
143
  {
127
144
  "--vars": {
128
- "start_date": "{{ context.partition_range_start }}",
129
- "end_date": "{{ context.partition_range_end }}",
145
+ "start_date": "{{ partition_range_start }}",
146
+ "end_date": "{{ partition_range_end }}",
130
147
  },
131
148
  },
132
149
  ],
@@ -192,6 +209,14 @@ class DbtProjectComponent(dg.Component, dg.Resolvable):
192
209
  ),
193
210
  ] = True
194
211
 
212
+ @property
213
+ def defs_state_config(self) -> DefsStateConfig:
214
+ return DefsStateConfig(
215
+ key=f"{self.__class__.__name__}[{self.project.name}]",
216
+ type=DefsStateManagementType.LOCAL_FILESYSTEM,
217
+ refresh_if_dev=self.prepare_if_dev,
218
+ )
219
+
195
220
  @cached_property
196
221
  def translator(self) -> "DagsterDbtTranslator":
197
222
  return DbtProjectComponentTranslator(self, self.translation_settings)
@@ -228,9 +253,19 @@ class DbtProjectComponent(dg.Component, dg.Resolvable):
228
253
  exclude=exclude,
229
254
  )
230
255
 
231
- def build_defs(self, context: dg.ComponentLoadContext) -> dg.Definitions:
232
- if self.prepare_if_dev:
233
- self.project.prepare_if_dev()
256
+ def write_state_to_path(self, state_path: Path) -> None:
257
+ # compile the manifest
258
+ self.project.preparer.prepare(self.project)
259
+ # move the manifest to the correct path
260
+ shutil.copyfile(self.project.manifest_path, state_path)
261
+
262
+ def build_defs_from_state(
263
+ self, context: dg.ComponentLoadContext, state_path: Optional[Path]
264
+ ) -> dg.Definitions:
265
+ if state_path is not None:
266
+ shutil.copyfile(state_path, self.project.manifest_path)
267
+
268
+ res_ctx = context.resolution_context
234
269
 
235
270
  @dbt_assets(
236
271
  manifest=self.project.manifest_path,
@@ -243,7 +278,8 @@ class DbtProjectComponent(dg.Component, dg.Resolvable):
243
278
  backfill_policy=self.op.backfill_policy if self.op else None,
244
279
  )
245
280
  def _fn(context: dg.AssetExecutionContext):
246
- yield from self.execute(context=context, dbt=self.cli_resource)
281
+ with _set_resolution_context(res_ctx):
282
+ yield from self.execute(context=context, dbt=self.cli_resource)
247
283
 
248
284
  return dg.Definitions(assets=[_fn])
249
285
 
@@ -258,15 +294,15 @@ class DbtProjectComponent(dg.Component, dg.Resolvable):
258
294
  except Exception:
259
295
  partition_time_window = None
260
296
 
261
- scope = dict(
262
- partition_key=partition_key,
263
- partition_key_range=partition_key_range,
264
- partition_time_window=partition_time_window,
265
- )
266
-
267
- # resolve the cli args with this additional scope
268
- resolved_args = ResolutionContext(scope=scope).resolve_value(
269
- self.cli_args, as_type=list[str]
297
+ # resolve the cli args with additional partition-related scope
298
+ resolved_args = (
299
+ _resolution_context.get()
300
+ .with_scope(
301
+ partition_key=partition_key,
302
+ partition_key_range=partition_key_range,
303
+ partition_time_window=partition_time_window,
304
+ )
305
+ .resolve_value(self.cli_args, as_type=list[str])
270
306
  )
271
307
 
272
308
  def _normalize_arg(arg: Union[str, dict[str, Any]]) -> list[str]:
@@ -15,6 +15,7 @@ from dagster._core.definitions.asset_checks.asset_check_evaluation import AssetC
15
15
  from dagster._core.definitions.metadata import TableMetadataSet, TextMetadataValue
16
16
  from dagster._core.errors import DagsterInvalidPropertyError
17
17
  from dagster._core.utils import exhaust_iterator_and_yield_results_with_exception, imap
18
+ from dagster._utils import pushd
18
19
  from typing_extensions import TypeVar
19
20
 
20
21
  from dagster_dbt.asset_utils import default_metadata_from_dbt_resource_props
@@ -31,6 +32,7 @@ DbtDagsterEventType = Union[
31
32
  Output, AssetMaterialization, AssetCheckResult, AssetObservation, AssetCheckEvaluation
32
33
  ]
33
34
 
35
+
34
36
  # We define DbtEventIterator as a generic type for the sake of type hinting.
35
37
  # This is so that users who inspect the type of the return value of `DbtCliInvocation.stream()`
36
38
  # will be able to see the inner type of the iterator, rather than just `DbtEventIterator`.
@@ -63,7 +65,10 @@ def _fetch_column_metadata(
63
65
 
64
66
  dbt_resource_props = _get_dbt_resource_props_from_event(invocation, event)
65
67
 
66
- with adapter.connection_named(f"column_metadata_{dbt_resource_props['unique_id']}"):
68
+ with (
69
+ pushd(str(invocation.project_dir)),
70
+ adapter.connection_named(f"column_metadata_{dbt_resource_props['unique_id']}"),
71
+ ):
67
72
  try:
68
73
  cols = invocation._get_columns_from_dbt_resource_props( # noqa: SLF001
69
74
  adapter=adapter, dbt_resource_props=dbt_resource_props
@@ -165,7 +170,10 @@ def _fetch_row_count_metadata(
165
170
  relation_name = dbt_resource_props["relation_name"]
166
171
 
167
172
  try:
168
- with adapter.connection_named(f"row_count_{unique_id}"):
173
+ with (
174
+ pushd(str(invocation.project_dir)),
175
+ adapter.connection_named(f"row_count_{unique_id}"),
176
+ ):
169
177
  query_result = adapter.execute(
170
178
  f"""
171
179
  SELECT
@@ -267,11 +275,12 @@ class DbtEventIterator(Iterator[T]):
267
275
  """
268
276
 
269
277
  def _map_fn(event: DbtDagsterEventType) -> DbtDagsterEventType:
270
- result = fn(self._dbt_cli_invocation, event)
271
- if result is None:
272
- return event
278
+ with pushd(str(self._dbt_cli_invocation.project_dir)):
279
+ result = fn(self._dbt_cli_invocation, event)
280
+ if result is None:
281
+ return event
273
282
 
274
- return event.with_metadata({**event.metadata, **result})
283
+ return event.with_metadata({**event.metadata, **result})
275
284
 
276
285
  # If the adapter is DuckDB, we need to wait for the dbt CLI process to complete
277
286
  # so that the DuckDB lock is released. This is because DuckDB does not allow for
dagster_dbt/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.27.14"
1
+ __version__ = "0.27.16"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dagster-dbt
3
- Version: 0.27.14
3
+ Version: 0.27.16
4
4
  Summary: A Dagster integration for dbt
5
5
  Home-page: https://github.com/dagster-io/dagster/tree/master/python_modules/libraries/dagster-dbt
6
6
  Author: Dagster Labs
@@ -15,7 +15,7 @@ Classifier: License :: OSI Approved :: Apache Software License
15
15
  Classifier: Operating System :: OS Independent
16
16
  Requires-Python: >=3.9,<3.14
17
17
  License-File: LICENSE
18
- Requires-Dist: dagster==1.11.14
18
+ Requires-Dist: dagster==1.11.16
19
19
  Requires-Dist: dbt-core<1.11,>=1.7
20
20
  Requires-Dist: Jinja2
21
21
  Requires-Dist: networkx
@@ -14,7 +14,7 @@ dagster_dbt/freshness_builder.py,sha256=hnyp6vYVxPTHR_v5ZBu43jwwDIL2oNXFW96BMWnS
14
14
  dagster_dbt/metadata_set.py,sha256=lqjASYoYeM_Ey6r8UsPUkRMwmuAIfFCFvkNm0xW5xTg,512
15
15
  dagster_dbt/py.typed,sha256=la67KBlbjXN-_-DfGNcdOcjYumVpKG_Tkw-8n5dnGB4,8
16
16
  dagster_dbt/utils.py,sha256=gT6xO7buRolkhc2fa5ySUPfD1eXo3e6RJWZAKkM6yFo,8513
17
- dagster_dbt/version.py,sha256=L7VpQaY2T34JkbqawqNFJ6nG-6vihOrlyqaDfc_Z1ww,24
17
+ dagster_dbt/version.py,sha256=gNIskoVbgqFeY6KiyOzkhfP7GLwnNVmVeil7tBvkL44,24
18
18
  dagster_dbt/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
19
  dagster_dbt/cli/app.py,sha256=9oBx85uzAkMtBdV39vNm5rxuAGPVYzzDUs6Ek-KL0XY,13516
20
20
  dagster_dbt/cloud/__init__.py,sha256=8WKaLuPl_pUG9Cv78GW782vrWQfqK8QtAWegkTxA9r4,441
@@ -34,12 +34,12 @@ dagster_dbt/cloud_v2/sensor_builder.py,sha256=8mAm-1ZFvoiVVdxSkSQbMxg18aQUY5kazu
34
34
  dagster_dbt/cloud_v2/types.py,sha256=dI-NIguj582LwTTMXdY5r0U4-INDn9anNy-ciGuEc1s,4136
35
35
  dagster_dbt/components/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
36
  dagster_dbt/components/dbt_project/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
- dagster_dbt/components/dbt_project/component.py,sha256=ntdocglYvgi7K0vnkPy3L7EuNiMNSljQKj0jKMsByis,13257
37
+ dagster_dbt/components/dbt_project/component.py,sha256=CDT0bDTVuYUr2gFZeNxdZ_ggI5NLXBAyavQFWmPlxyQ,14622
38
38
  dagster_dbt/components/dbt_project/scaffolder.py,sha256=AqwRnX3cFpvCSxEeEpyQj0Vei84WSWUi2BIMCtkxaDE,1893
39
39
  dagster_dbt/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
40
  dagster_dbt/core/dbt_cli_event.py,sha256=Yqr-UuzFF7jIcI4KRAmiAhGTX9Ay0tIMN2NaJegsrJQ,25203
41
41
  dagster_dbt/core/dbt_cli_invocation.py,sha256=7ZrwAgivAtZGwrHLxfpmNan004IuEEdBSaKZeKp69Mg,17534
42
- dagster_dbt/core/dbt_event_iterator.py,sha256=F2SwLOxCeTzfSGWav9oRp-tyzf7SHCaWhhZuyYWAZK4,16702
42
+ dagster_dbt/core/dbt_event_iterator.py,sha256=s0gU6wIgOpmbo50309FHp9zTqlLkIWcgLkETmidxPRo,16953
43
43
  dagster_dbt/core/resource.py,sha256=6HhBBa8SRAJPhDtnHRNPTjdFPQvNYIdfAXQY3_LdqHk,30782
44
44
  dagster_dbt/core/utils.py,sha256=ciXjLhFTNVTyDtVWP4Kjee0LWZkIuVJOltvlv0COzDo,577
45
45
  dagster_dbt/include/__init__.py,sha256=8ujr-ROlJ5x64POs-bH-0zfjZ2QHx-FgKUZAvAFbSs8,89
@@ -50,9 +50,9 @@ dagster_dbt/include/scaffold/assets.py.jinja,sha256=JImqnDUP5ewy8RVti4IuXL70yJno
50
50
  dagster_dbt/include/scaffold/definitions.py.jinja,sha256=Hou7emwkEeh5YXTdqjYFrAc2SK-Q6MgTNsQOKA_Vy3s,364
51
51
  dagster_dbt/include/scaffold/project.py.jinja,sha256=YNtkT5Hq4VbGw-b7QcxdelhXsesIKORwVuBFGFdfeUs,432
52
52
  dagster_dbt/include/scaffold/schedules.py.jinja,sha256=Xua_VtPjYFc498A5uaBGQ36GwV1gqciO4P3D8Yt9M-Y,413
53
- dagster_dbt-0.27.14.dist-info/licenses/LICENSE,sha256=4lsMW-RCvfVD4_F57wrmpe3vX1xwUk_OAKKmV_XT7Z0,11348
54
- dagster_dbt-0.27.14.dist-info/METADATA,sha256=zfSm81swDpXXBB9F5Lwn5NLmibgFaN-AORjs_tLa7Go,1598
55
- dagster_dbt-0.27.14.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
56
- dagster_dbt-0.27.14.dist-info/entry_points.txt,sha256=pbv0tVoTB7cByG-noE8rC6atvthh64qBaTo7PkQ9HbM,163
57
- dagster_dbt-0.27.14.dist-info/top_level.txt,sha256=hoOwFvw9OpJUN1azE6UVHcxMKqhUwR_BTN0Ay-iKUDA,12
58
- dagster_dbt-0.27.14.dist-info/RECORD,,
53
+ dagster_dbt-0.27.16.dist-info/licenses/LICENSE,sha256=4lsMW-RCvfVD4_F57wrmpe3vX1xwUk_OAKKmV_XT7Z0,11348
54
+ dagster_dbt-0.27.16.dist-info/METADATA,sha256=ssXVSSXpCDfHTzVJrVqqX0gsWHO2EegWwC5sGLelNMw,1598
55
+ dagster_dbt-0.27.16.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
56
+ dagster_dbt-0.27.16.dist-info/entry_points.txt,sha256=pbv0tVoTB7cByG-noE8rC6atvthh64qBaTo7PkQ9HbM,163
57
+ dagster_dbt-0.27.16.dist-info/top_level.txt,sha256=hoOwFvw9OpJUN1azE6UVHcxMKqhUwR_BTN0Ay-iKUDA,12
58
+ dagster_dbt-0.27.16.dist-info/RECORD,,