Skip to content

Commit bdac101

Browse files
committed
Fix: Support blueprint variables in jinja macros
1 parent 7938dbd commit bdac101

3 files changed

Lines changed: 57 additions & 2 deletions

File tree

sqlmesh/core/constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
SQLMESH_BLUEPRINT_VARS = "__sqlmesh__blueprint__vars__"
8080

8181
VAR = "var"
82+
BLUEPRINT_VAR = "blueprint_var"
8283
GATEWAY = "gateway"
8384

8485
SQLMESH_MACRO = "__sqlmesh__macro__"

sqlmesh/utils/jinja.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from sqlmesh.core import dialect as d
1616
from sqlmesh.utils import AttributeDict
1717
from sqlmesh.utils.pydantic import PRIVATE_FIELDS, PydanticModel, field_serializer, field_validator
18+
from sqlmesh.utils.metaprogramming import SqlValue
1819

1920

2021
if t.TYPE_CHECKING:
@@ -593,7 +594,10 @@ def jinja_call_arg_name(node: nodes.Node) -> str:
593594

594595
def create_var(variables: t.Dict[str, t.Any]) -> t.Callable:
595596
def _var(var_name: str, default: t.Optional[t.Any] = None) -> t.Optional[t.Any]:
596-
return variables.get(var_name.lower(), default)
597+
value = variables.get(var_name.lower(), default)
598+
if isinstance(value, SqlValue):
599+
return value.sql
600+
return value
597601

598602
return _var
599603

@@ -603,10 +607,12 @@ def create_builtin_globals(
603607
) -> t.Dict[str, t.Any]:
604608
global_vars.pop(c.GATEWAY, None)
605609
variables = global_vars.pop(c.SQLMESH_VARS, None) or {}
610+
blueprint_variables = global_vars.pop(c.SQLMESH_BLUEPRINT_VARS, None) or {}
606611
return {
612+
**global_vars,
607613
c.VAR: create_var(variables),
608614
c.GATEWAY: lambda: variables.get(c.GATEWAY, None),
609-
**global_vars,
615+
c.BLUEPRINT_VAR: create_var(blueprint_variables),
610616
}
611617

612618

tests/core/test_model.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8662,6 +8662,54 @@ def test_blueprint_variable_precedence_sql(tmp_path: Path, assert_exp_eq: t.Call
86628662
)
86638663

86648664

8665+
def test_blueprint_variable_jinja(tmp_path: Path, assert_exp_eq: t.Callable) -> None:
8666+
init_example_project(tmp_path, dialect="duckdb", template=ProjectTemplate.EMPTY)
8667+
8668+
blueprint_variables = tmp_path / "models/blueprint_variables.sql"
8669+
blueprint_variables.parent.mkdir(parents=True, exist_ok=True)
8670+
blueprint_variables.write_text(
8671+
"""
8672+
MODEL (
8673+
name s.@{bp_name},
8674+
blueprints (
8675+
(bp_name := m1, var1 := 'v1', var2 := v2),
8676+
(bp_name := m2, var1 := 'v3'),
8677+
),
8678+
);
8679+
8680+
@DEF(bp_name, override);
8681+
8682+
JINJA_QUERY_BEGIN;
8683+
SELECT
8684+
{{ blueprint_var('var1') }} AS var1,
8685+
'{{ blueprint_var('var2') }}' AS var2,
8686+
'{{ blueprint_var('var2', 'var2_default') }}' AS var2_default,
8687+
'{{ blueprint_var('bp_name') }}' AS bp_name;
8688+
JINJA_END;
8689+
"""
8690+
)
8691+
ctx = Context(
8692+
config=Config(
8693+
model_defaults=ModelDefaultsConfig(dialect="duckdb"),
8694+
variables={"var2": "1"},
8695+
),
8696+
paths=tmp_path,
8697+
)
8698+
assert len(ctx.models) == 2
8699+
8700+
m1 = ctx.get_model("s.m1", raise_if_missing=True)
8701+
m2 = ctx.get_model("s.m2", raise_if_missing=True)
8702+
8703+
assert_exp_eq(
8704+
m1.render_query(),
8705+
"""SELECT 'v1' AS "var1", 'v2' AS "var2", 'v2' AS "var2_default", 'm1' AS "bp_name";""",
8706+
)
8707+
assert_exp_eq(
8708+
m2.render_query(),
8709+
"""SELECT 'v3' AS "var1", 'None' AS "var2", 'var2_default' AS "var2_default", 'm2' AS "bp_name";""",
8710+
)
8711+
8712+
86658713
def test_blueprint_variable_precedence_python(tmp_path: Path, mocker: MockerFixture) -> None:
86668714
init_example_project(tmp_path, dialect="duckdb", template=ProjectTemplate.EMPTY)
86678715

0 commit comments

Comments
 (0)