Skip to content

Commit 48e6775

Browse files
authored
Feat dbt incremental allow partials (#3709)
1 parent 928e870 commit 48e6775

4 files changed

Lines changed: 49 additions & 3 deletions

File tree

docs/integrations/dbt.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,8 @@ The [`lookback` parameter](../concepts/models/overview.md#lookback) is used to c
201201
202202
**Note:** By default, all incremental dbt models are configured to be [forward-only](../concepts/plans.md#forward-only-plans). However, you can change this behavior by setting the `forward_only: false` setting either in the configuration of an individual model or globally for all models in the `dbt_project.yaml` file. The [forward-only](../concepts/plans.md#forward-only-plans) mode aligns more closely with the typical operation of dbt and therefore better meets user's expectations.
203203
204+
Similarly, the [allow_partials](../concepts/models/overview.md#allow_partials) parameter is set to `true` by default for incremental dbt models unless the time column is specified, or the `allow_partials` parameter is explicitly set to `false` in the model configuration.
205+
204206
#### on_schema_change
205207
206208
SQLMesh automatically detects destructive schema changes to [forward-only incremental models](../guides/incremental_time.md#forward-only-models) and to all incremental models in [forward-only plans](../concepts/plans.md#destructive-changes).

sqlmesh/dbt/common.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,10 @@ def sqlmesh_config_kwargs(self) -> t.Dict[str, t.Any]:
149149
"""
150150
kwargs = {}
151151
for field in self.sqlmesh_config_fields:
152-
field_val = getattr(self, field, None) or self.meta.get(field, None)
153-
if field_val:
152+
field_val = getattr(self, field, None)
153+
if field_val is None:
154+
field_val = self.meta.get(field, None)
155+
if field_val is not None:
154156
kwargs[field] = field_val
155157
return kwargs
156158

sqlmesh/dbt/model.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -554,17 +554,26 @@ def to_sqlmesh(
554554
if physical_properties:
555555
model_kwargs["physical_properties"] = physical_properties
556556

557+
kind = self.model_kind(context)
558+
allow_partials = model_kwargs.pop("allow_partials", None)
559+
if allow_partials is None and (
560+
kind.is_incremental_unmanaged or kind.is_incremental_by_unique_key
561+
):
562+
# Set allow_partials to True for dbt incremental models to preserve the original semantics.
563+
allow_partials = True
564+
557565
model = create_sql_model(
558566
self.canonical_name(context),
559567
query,
560568
dialect=model_dialect,
561-
kind=self.model_kind(context),
569+
kind=kind,
562570
start=self.start,
563571
audit_definitions=audit_definitions,
564572
# This ensures that we bypass query rendering that would otherwise be required to extract additional
565573
# dependencies from the model's SQL.
566574
# Note: any table dependencies that are not referenced using the `ref` macro will not be included.
567575
extract_dependencies_from_query=False,
576+
allow_partials=allow_partials,
568577
**optional_kwargs,
569578
**model_kwargs,
570579
)

tests/dbt/test_transformation.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1450,3 +1450,36 @@ def test_refs_in_jinja_globals(sushi_test_project: Project, mocker: MockerFixtur
14501450
"waiter_revenue_by_day",
14511451
"sushi.waiter_revenue_by_day",
14521452
}
1453+
1454+
1455+
def test_dbt_incremental_allow_partials_by_default():
1456+
context = DbtContext()
1457+
context._target = SnowflakeConfig(
1458+
name="target",
1459+
schema="test",
1460+
database="test",
1461+
account="account",
1462+
user="user",
1463+
password="password",
1464+
)
1465+
1466+
model = ModelConfig(
1467+
name="model",
1468+
alias="model",
1469+
package_name="package",
1470+
target_schema="test",
1471+
sql="SELECT * FROM baz",
1472+
materialized=Materialization.TABLE.value,
1473+
)
1474+
assert model.allow_partials is None
1475+
assert not model.to_sqlmesh(context).allow_partials
1476+
1477+
model.materialized = Materialization.INCREMENTAL.value
1478+
assert model.allow_partials is None
1479+
assert model.to_sqlmesh(context).allow_partials
1480+
1481+
model.allow_partials = True
1482+
assert model.to_sqlmesh(context).allow_partials
1483+
1484+
model.allow_partials = False
1485+
assert not model.to_sqlmesh(context).allow_partials

0 commit comments

Comments
 (0)