Skip to content

Commit 83e7053

Browse files
Fix: Enable unit testing in Python models with upstream tables (#4302)
1 parent fce766b commit 83e7053

2 files changed

Lines changed: 56 additions & 2 deletions

File tree

sqlmesh/core/test/context.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,12 @@ def __init__(
3939
@cached_property
4040
def _model_tables(self) -> t.Dict[str, str]:
4141
"""Returns a mapping of model names to tables."""
42+
43+
# Include upstream dependencies to ensure they can be resolved during test execution
4244
return {
43-
name: self._test._test_fixture_table(name).sql() for name, model in self._models.items()
45+
name: self._test._test_fixture_table(name).sql()
46+
for model in self._models.values()
47+
for name in [model.name, *model.depends_on]
4448
}
4549

4650
def with_variables(

tests/core/test_test.py

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
GatewayConfig,
2222
ModelDefaultsConfig,
2323
)
24-
from sqlmesh.core.context import Context
24+
from sqlmesh.core.context import Context, ExecutionContext
2525
from sqlmesh.core.console import get_console
2626
from sqlmesh.core.dialect import parse
2727
from sqlmesh.core.engine_adapter import EngineAdapter
@@ -2470,3 +2470,53 @@ def execute(context, start, end, execution_time, **kwargs):
24702470

24712471
results = ctx.test()
24722472
assert len(results.successes) == 30
2473+
2474+
2475+
def test_python_model_upstream_table(sushi_context) -> None:
2476+
@model(
2477+
"test_upstream_table_python",
2478+
columns={"customer_id": "int", "zip": "str"},
2479+
)
2480+
def upstream_table_python(context, **kwargs):
2481+
demographics_external_table = context.resolve_table("memory.raw.demographics")
2482+
return context.fetchdf(
2483+
exp.select("customer_id", "zip").from_(demographics_external_table),
2484+
)
2485+
2486+
python_model = model.get_registry()["test_upstream_table_python"].model(
2487+
module_path=Path("."),
2488+
path=Path("."),
2489+
)
2490+
2491+
context = ExecutionContext(sushi_context.engine_adapter, sushi_context.snapshots, None, None)
2492+
df = list(python_model.render(context=context))[0]
2493+
2494+
# Verify the actual model output matches the expected actual external table's values
2495+
assert df.to_dict(orient="records") == [{"customer_id": 1, "zip": "00000"}]
2496+
2497+
# Use different input values for the test and verify the outputs
2498+
_check_successful_or_raise(
2499+
_create_test(
2500+
body=load_yaml("""
2501+
test_test_upstream_table_python:
2502+
model: test_upstream_table_python
2503+
inputs:
2504+
memory.raw.demographics:
2505+
- customer_id: 12
2506+
zip: "S11HA"
2507+
- customer_id: 555
2508+
zip: "94401"
2509+
outputs:
2510+
query:
2511+
- customer_id: 12
2512+
zip: "S11HA"
2513+
- customer_id: 555
2514+
zip: "94401"
2515+
"""),
2516+
test_name="test_test_upstream_table_python",
2517+
model=model.get_registry()["test_upstream_table_python"].model(
2518+
module_path=Path("."), path=Path(".")
2519+
),
2520+
context=sushi_context,
2521+
).run()
2522+
)

0 commit comments

Comments
 (0)