Skip to content

Commit 471b459

Browse files
Feat(dbt): Add support for selected resources context variable
1 parent 84b3901 commit 471b459

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
@@ -1582,6 +1583,11 @@ def plan_builder(
15821583
"Selector did not return any models. Please check your model selection and try again."
15831584
)
15841585

1586+
if self._project_type != c.NATIVE:
1587+
set_selected_resources(
1588+
models=model_selector.expand_model_selections(select_models or "*")
1589+
)
1590+
15851591
snapshots = self._snapshots(models_override)
15861592
context_diff = self._context_diff(
15871593
environment or c.PROD,
@@ -2482,6 +2488,9 @@ def _run(
24822488
select_models, no_auto_upstream, snapshots.values()
24832489
)
24842490

2491+
if self._project_type != c.NATIVE:
2492+
set_selected_resources(models=select_models or set([s.name for s in snapshots.keys()]))
2493+
24852494
completion_status = scheduler.run(
24862495
environment,
24872496
start=start,

sqlmesh/dbt/builtin.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,7 @@ def create_builtin_globals(
459459
"run_query": sql_execution.run_query,
460460
"statement": sql_execution.statement,
461461
"graph": adapter.graph,
462+
"selected_resources": get_selected_resources(),
462463
}
463464
)
464465

@@ -485,3 +486,33 @@ def _relation_info_to_relation(
485486
}
486487
)
487488
return relation_type.create(**relation_info, quote_policy=quote_policy)
489+
490+
491+
_selected_resources: t.List[str] = []
492+
493+
494+
def set_selected_resources(
495+
models: t.Optional[t.Set[str]] = None,
496+
) -> None:
497+
global _selected_resources
498+
resources = []
499+
500+
if models:
501+
for model in models:
502+
resources.append(dbt_model_id(model))
503+
504+
_selected_resources = sorted(resources)
505+
506+
507+
def dbt_model_id(sqlmesh_model_name: str) -> str:
508+
parts = [part.strip('"') for part in sqlmesh_model_name.split(".")]
509+
return f"model.{parts[0]}.{parts[-1]}"
510+
511+
512+
def get_selected_resources() -> t.List[str]:
513+
return _selected_resources
514+
515+
516+
def clear_selected_resources() -> None:
517+
global _selected_resources
518+
_selected_resources = []

tests/dbt/test_transformation.py

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,13 @@
4242
OnAdditiveChange,
4343
)
4444
from sqlmesh.core.state_sync.db.snapshot import _snapshot_to_json
45-
from sqlmesh.dbt.builtin import _relation_info_to_relation
4645
from sqlmesh.dbt.common import Dependencies
46+
from sqlmesh.dbt.builtin import (
47+
_relation_info_to_relation,
48+
dbt_model_id,
49+
clear_selected_resources,
50+
get_selected_resources,
51+
)
4752
from sqlmesh.dbt.column import (
4853
ColumnConfig,
4954
column_descriptions_to_sqlmesh,
@@ -2034,3 +2039,68 @@ def test_dynamic_var_names_in_macro(sushi_test_project: Project):
20342039
)
20352040
converted_model = model_config.to_sqlmesh(context)
20362041
assert "dynamic_test_var" in converted_model.jinja_macros.global_objs["vars"] # type: ignore
2042+
2043+
2044+
def test_selected_resources_with_selectors():
2045+
sushi_context = Context(paths=["tests/fixtures/dbt/sushi_test"])
2046+
2047+
# A plan with a specific model selection
2048+
clear_selected_resources()
2049+
sushi_context.plan_builder(select_models=["sushi.customers"])
2050+
2051+
selected = get_selected_resources()
2052+
assert "model.memory.customers" in selected
2053+
assert len(selected) == 1
2054+
2055+
# Plan without model selections
2056+
clear_selected_resources()
2057+
sushi_context.plan_builder()
2058+
selected = get_selected_resources()
2059+
assert sorted(
2060+
[
2061+
"model.memory.customer_revenue_by_day",
2062+
"model.memory.customers",
2063+
"model.memory.items",
2064+
"model.memory.items_check_snapshot",
2065+
"model.memory.items_no_hard_delete_snapshot",
2066+
"model.memory.items_snapshot",
2067+
"model.memory.order_items",
2068+
"model.memory.orders",
2069+
"model.memory.simple_model_a",
2070+
"model.memory.simple_model_b",
2071+
"model.memory.top_waiters",
2072+
"model.memory.waiter_as_customer_by_day",
2073+
"model.memory.waiter_names",
2074+
"model.memory.waiter_revenue_by_day_v1",
2075+
"model.memory.waiter_revenue_by_day_v2",
2076+
"model.memory.waiters",
2077+
]
2078+
) == sorted(selected)
2079+
2080+
# Test with downstream models as well
2081+
clear_selected_resources()
2082+
sushi_context.plan_builder(select_models=["sushi.customers+"])
2083+
selected = get_selected_resources()
2084+
assert sorted(["model.memory.customers", "model.memory.waiter_as_customer_by_day"]) == sorted(
2085+
selected
2086+
)
2087+
2088+
# Test wildcard selection
2089+
clear_selected_resources()
2090+
sushi_context.plan_builder(select_models=["sushi.waiter_*"])
2091+
selected = get_selected_resources()
2092+
assert sorted(
2093+
[
2094+
"model.memory.waiter_as_customer_by_day",
2095+
"model.memory.waiter_names",
2096+
"model.memory.waiter_revenue_by_day_v1",
2097+
"model.memory.waiter_revenue_by_day_v2",
2098+
]
2099+
) == sorted(selected)
2100+
clear_selected_resources()
2101+
2102+
2103+
def test_dbt_model_id_conversion():
2104+
assert dbt_model_id("jaffle_shop.main.customers") == "model.jaffle_shop.customers"
2105+
assert dbt_model_id("jaffle_shop.main.orders") == "model.jaffle_shop.orders"
2106+
assert dbt_model_id('"jaffle_shop"."customers"') == "model.jaffle_shop.customers"

0 commit comments

Comments
 (0)