Skip to content

Commit 515dcd1

Browse files
Feat(dbt): Add support for selected resources context variable
1 parent 59f8b2e commit 515dcd1

File tree

3 files changed

+111
-1
lines changed

3 files changed

+111
-1
lines changed

sqlmesh/core/context.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@
117117
run_tests,
118118
)
119119
from sqlmesh.core.user import User
120+
from sqlmesh.dbt.builtin import set_selected_resources
120121
from sqlmesh.utils import UniqueKeyDict, Verbosity
121122
from sqlmesh.utils.concurrency import concurrent_apply_to_values
122123
from sqlmesh.utils.dag import DAG
@@ -1564,6 +1565,11 @@ def plan_builder(
15641565
"Selector did not return any models. Please check your model selection and try again."
15651566
)
15661567

1568+
if self._project_type != c.NATIVE:
1569+
set_selected_resources(
1570+
models=model_selector.expand_model_selections(select_models or "*")
1571+
)
1572+
15671573
snapshots = self._snapshots(models_override)
15681574
context_diff = self._context_diff(
15691575
environment or c.PROD,
@@ -2463,6 +2469,9 @@ def _run(
24632469
select_models, no_auto_upstream, snapshots.values()
24642470
)
24652471

2472+
if self._project_type != c.NATIVE:
2473+
set_selected_resources(models=select_models or set([s.name for s in snapshots.keys()]))
2474+
24662475
completion_status = scheduler.run(
24672476
environment,
24682477
start=start,

sqlmesh/dbt/builtin.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,7 @@ def create_builtin_globals(
452452
"load_result": sql_execution.load_result,
453453
"run_query": sql_execution.run_query,
454454
"statement": sql_execution.statement,
455+
"selected_resources": get_selected_resources(),
455456
}
456457
)
457458

@@ -478,3 +479,33 @@ def _relation_info_to_relation(
478479
}
479480
)
480481
return relation_type.create(**relation_info, quote_policy=quote_policy)
482+
483+
484+
_selected_resources: t.List[str] = []
485+
486+
487+
def set_selected_resources(
488+
models: t.Optional[t.Set[str]] = None,
489+
) -> None:
490+
global _selected_resources
491+
resources = []
492+
493+
if models:
494+
for model in models:
495+
resources.append(dbt_model_id(model))
496+
497+
_selected_resources = sorted(resources)
498+
499+
500+
def dbt_model_id(sqlmesh_model_name: str) -> str:
501+
parts = [part.strip('"') for part in sqlmesh_model_name.split(".")]
502+
return f"model.{parts[0]}.{parts[-1]}"
503+
504+
505+
def get_selected_resources() -> t.List[str]:
506+
return _selected_resources
507+
508+
509+
def clear_selected_resources() -> None:
510+
global _selected_resources
511+
_selected_resources = []

tests/dbt/test_transformation.py

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,12 @@
3131
)
3232
from sqlmesh.core.model.kind import SCDType2ByColumnKind, SCDType2ByTimeKind
3333
from sqlmesh.core.state_sync.db.snapshot import _snapshot_to_json
34-
from sqlmesh.dbt.builtin import _relation_info_to_relation
34+
from sqlmesh.dbt.builtin import (
35+
_relation_info_to_relation,
36+
dbt_model_id,
37+
clear_selected_resources,
38+
get_selected_resources,
39+
)
3540
from sqlmesh.dbt.column import (
3641
ColumnConfig,
3742
column_descriptions_to_sqlmesh,
@@ -1694,3 +1699,68 @@ def test_on_run_start_end():
16941699
"CREATE OR REPLACE TABLE schema_table_sushi__dev_nested_package AS SELECT 'sushi__dev' AS schema",
16951700
]
16961701
)
1702+
1703+
1704+
def test_selected_resources_with_selectors():
1705+
sushi_context = Context(paths=["tests/fixtures/dbt/sushi_test"])
1706+
1707+
# A plan with a specific model selection
1708+
clear_selected_resources()
1709+
sushi_context.plan_builder(select_models=["sushi.customers"])
1710+
1711+
selected = get_selected_resources()
1712+
assert "model.memory.customers" in selected
1713+
assert len(selected) == 1
1714+
1715+
# Plan without model selections
1716+
clear_selected_resources()
1717+
sushi_context.plan_builder()
1718+
selected = get_selected_resources()
1719+
assert sorted(
1720+
[
1721+
"model.memory.customer_revenue_by_day",
1722+
"model.memory.customers",
1723+
"model.memory.items",
1724+
"model.memory.items_check_snapshot",
1725+
"model.memory.items_no_hard_delete_snapshot",
1726+
"model.memory.items_snapshot",
1727+
"model.memory.order_items",
1728+
"model.memory.orders",
1729+
"model.memory.simple_model_a",
1730+
"model.memory.simple_model_b",
1731+
"model.memory.top_waiters",
1732+
"model.memory.waiter_as_customer_by_day",
1733+
"model.memory.waiter_names",
1734+
"model.memory.waiter_revenue_by_day_v1",
1735+
"model.memory.waiter_revenue_by_day_v2",
1736+
"model.memory.waiters",
1737+
]
1738+
) == sorted(selected)
1739+
1740+
# Test with downstream models as well
1741+
clear_selected_resources()
1742+
sushi_context.plan_builder(select_models=["sushi.customers+"])
1743+
selected = get_selected_resources()
1744+
assert sorted(["model.memory.customers", "model.memory.waiter_as_customer_by_day"]) == sorted(
1745+
selected
1746+
)
1747+
1748+
# Test wildcard selection
1749+
clear_selected_resources()
1750+
sushi_context.plan_builder(select_models=["sushi.waiter_*"])
1751+
selected = get_selected_resources()
1752+
assert sorted(
1753+
[
1754+
"model.memory.waiter_as_customer_by_day",
1755+
"model.memory.waiter_names",
1756+
"model.memory.waiter_revenue_by_day_v1",
1757+
"model.memory.waiter_revenue_by_day_v2",
1758+
]
1759+
) == sorted(selected)
1760+
clear_selected_resources()
1761+
1762+
1763+
def test_dbt_model_id_conversion():
1764+
assert dbt_model_id("jaffle_shop.main.customers") == "model.jaffle_shop.customers"
1765+
assert dbt_model_id("jaffle_shop.main.orders") == "model.jaffle_shop.orders"
1766+
assert dbt_model_id('"jaffle_shop"."customers"') == "model.jaffle_shop.customers"

0 commit comments

Comments
 (0)