Skip to content

Commit 66f2bf7

Browse files
authored
Fix: Detection of referenced variables in Python SQL models (#2743)
1 parent 2f51da5 commit 66f2bf7

File tree

2 files changed

+47
-4
lines changed

2 files changed

+47
-4
lines changed

sqlmesh/core/model/definition.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1636,6 +1636,8 @@ def create_sql_model(
16361636
used_variables=used_variables,
16371637
path=path,
16381638
)
1639+
else:
1640+
python_env = _add_variables_to_python_env(python_env, used_variables, variables)
16391641

16401642
return _create_model(
16411643
SqlModel,
@@ -1716,6 +1718,8 @@ def create_seed_model(
17161718
used_variables=used_variables,
17171719
path=path,
17181720
)
1721+
else:
1722+
python_env = _add_variables_to_python_env(python_env, used_variables, variables)
17191723

17201724
return _create_model(
17211725
SeedModel,
@@ -1999,15 +2003,22 @@ def _python_env(
19992003
build_env(used_macro.func, env=python_env, name=name, path=module_path)
20002004

20012005
serialized_env.update(serialize_env(python_env, path=module_path))
2006+
return _add_variables_to_python_env(serialized_env, used_variables, variables)
2007+
20022008

2003-
_, python_used_variables = _parse_dependencies(serialized_env, None)
2004-
used_variables |= python_used_variables
2009+
def _add_variables_to_python_env(
2010+
python_env: t.Dict[str, Executable],
2011+
used_variables: t.Optional[t.Set[str]],
2012+
variables: t.Optional[t.Dict[str, t.Any]],
2013+
) -> t.Dict[str, Executable]:
2014+
_, python_used_variables = _parse_dependencies(python_env, None)
2015+
used_variables = (used_variables or set()) | python_used_variables
20052016

20062017
variables = {k: v for k, v in (variables or {}).items() if k in used_variables}
20072018
if variables:
2008-
serialized_env[c.SQLMESH_VARS] = Executable.value(variables)
2019+
python_env[c.SQLMESH_VARS] = Executable.value(variables)
20092020

2010-
return serialized_env
2021+
return python_env
20112022

20122023

20132024
def _parse_dependencies(

tests/core/test_model.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4093,6 +4093,38 @@ def model_with_variables(context, **kwargs):
40934093
assert df.to_dict(orient="records") == [{"a": "test_value", "b": "default_value", "c": None}]
40944094

40954095

4096+
def test_variables_python_sql_model(mocker: MockerFixture) -> None:
4097+
@model(
4098+
"test_variables_python_model",
4099+
is_sql=True,
4100+
kind="full",
4101+
columns={"a": "string", "b": "string", "c": "string"},
4102+
)
4103+
def model_with_variables(evaluator, **kwargs):
4104+
return exp.select(
4105+
exp.convert(evaluator.var("TEST_VAR_A")).as_("a"),
4106+
exp.convert(evaluator.var("test_var_b", "default_value")).as_("b"),
4107+
exp.convert(evaluator.var("test_var_c")).as_("c"),
4108+
)
4109+
4110+
python_sql_model = model.get_registry()["test_variables_python_model"].model(
4111+
module_path=Path("."),
4112+
path=Path("."),
4113+
variables={"test_var_a": "test_value", "test_var_unused": 2},
4114+
)
4115+
4116+
assert python_sql_model.python_env[c.SQLMESH_VARS] == Executable.value(
4117+
{"test_var_a": "test_value"}
4118+
)
4119+
4120+
context = ExecutionContext(mocker.Mock(), {}, None, None)
4121+
query = list(python_sql_model.render(context=context))[0]
4122+
assert (
4123+
query.sql()
4124+
== """SELECT 'test_value' AS "a", 'default_value' AS "b", NULL AS "c" """.strip()
4125+
)
4126+
4127+
40964128
def test_named_variables_python_model(mocker: MockerFixture) -> None:
40974129
@model(
40984130
"test_named_variables_python_model",

0 commit comments

Comments
 (0)