Skip to content

Commit 79249dd

Browse files
Fix: Set dbt execute variable for parse time and run time accordingly
1 parent cd37002 commit 79249dd

File tree

5 files changed

+64
-7
lines changed

5 files changed

+64
-7
lines changed

sqlmesh/dbt/builtin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,7 @@ def create_builtin_globals(
533533
builtin_globals.update(
534534
{
535535
"adapter": adapter,
536-
"execute": True,
536+
"execute": isinstance(adapter, RuntimeAdapter),
537537
"load_relation": adapter.load_relation,
538538
"store_result": sql_execution.store_result,
539539
"load_result": sql_execution.load_result,

tests/core/test_integration.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2068,21 +2068,22 @@ def test_dbt_is_incremental_table_is_missing(sushi_test_dbt_context: Context):
20682068
assert context.engine_adapter.table_exists(snapshot.table_name())
20692069

20702070

2071+
@pytest.mark.xdist_group("dbt_manifest")
20712072
def test_model_attr(sushi_test_dbt_context: Context, assert_exp_eq):
20722073
context = sushi_test_dbt_context
20732074
model = context.get_model("sushi.top_waiters")
20742075
assert_exp_eq(
20752076
model.render_query(),
20762077
"""
20772078
SELECT
2078-
CAST("waiter_id" AS INT) AS "waiter_id",
2079-
CAST("revenue" AS DOUBLE) AS "revenue",
2079+
CAST("waiter_revenue_by_day_v2"."waiter_id" AS INT) AS "waiter_id",
2080+
CAST("waiter_revenue_by_day_v2"."revenue" AS DOUBLE) AS "revenue",
20802081
3 AS "model_columns"
20812082
FROM "memory"."sushi"."waiter_revenue_by_day_v2" AS "waiter_revenue_by_day_v2"
20822083
WHERE
2083-
"ds" = (
2084+
"waiter_revenue_by_day_v2"."ds" = (
20842085
SELECT
2085-
MAX("ds")
2086+
MAX("waiter_revenue_by_day_v2"."ds") AS "_col_0"
20862087
FROM "memory"."sushi"."waiter_revenue_by_day_v2" AS "waiter_revenue_by_day_v2"
20872088
)
20882089
ORDER BY

tests/dbt/test_transformation.py

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from pathlib import Path
77
from unittest.mock import patch
88

9+
from sqlmesh.dbt.adapter import ParsetimeAdapter, RuntimeAdapter
910
from sqlmesh.dbt.util import DBT_VERSION
1011

1112
import pytest
@@ -43,7 +44,7 @@
4344
OnAdditiveChange,
4445
)
4546
from sqlmesh.core.state_sync.db.snapshot import _snapshot_to_json
46-
from sqlmesh.dbt.builtin import _relation_info_to_relation, Config
47+
from sqlmesh.dbt.builtin import _relation_info_to_relation, Config, create_builtin_globals
4748
from sqlmesh.dbt.common import Dependencies
4849
from sqlmesh.dbt.column import (
4950
ColumnConfig,
@@ -64,7 +65,7 @@
6465
)
6566
from sqlmesh.dbt.test import TestConfig
6667
from sqlmesh.utils.errors import ConfigError, MacroEvalError, SQLMeshError
67-
from sqlmesh.utils.jinja import MacroReference
68+
from sqlmesh.utils.jinja import JinjaMacroRegistry, MacroReference
6869

6970
pytestmark = [pytest.mark.dbt, pytest.mark.slow]
7071

@@ -2352,3 +2353,47 @@ def test_dynamic_var_names_in_macro(sushi_test_project: Project):
23522353
)
23532354
converted_model = model_config.to_sqlmesh(context)
23542355
assert "dynamic_test_var" in converted_model.jinja_macros.global_objs["vars"] # type: ignore
2356+
2357+
2358+
@pytest.mark.xdist_group("dbt_manifest")
2359+
def test_execute_variable_parse_vs_runtime(sushi_test_dbt_context: Context):
2360+
execute_model = sushi_test_dbt_context.get_model('"memory"."sushi"."execute_test_model"')
2361+
parse_time_query = execute_model.render_query()
2362+
if parse_time_query:
2363+
parse_sql = parse_time_query.sql()
2364+
# should contain parse-time placeholders
2365+
assert "parse_time_placeholder" in parse_sql or "parse_time_context" in parse_sql
2366+
2367+
runtime_query = execute_model.render_query_or_raise(
2368+
engine_adapter=sushi_test_dbt_context.engine_adapter
2369+
)
2370+
runtime_sql = runtime_query.sql()
2371+
# At runtime, the macro should have executed the query and returned the result
2372+
assert "1" in runtime_sql or "runtime_context" in runtime_sql
2373+
2374+
2375+
@pytest.mark.xdist_group("dbt_manifest")
2376+
def test_execute_globals(mocker: MockerFixture):
2377+
# No engine adapter shoulde create parse adapter
2378+
parse_time_globals = create_builtin_globals(
2379+
jinja_macros=JinjaMacroRegistry(),
2380+
jinja_globals={},
2381+
engine_adapter=None,
2382+
)
2383+
2384+
assert parse_time_globals["execute"] is False
2385+
assert parse_time_globals["flags"].WHICH == "parse"
2386+
assert isinstance(parse_time_globals["adapter"], ParsetimeAdapter)
2387+
2388+
mock_engine_adapter = mocker.Mock()
2389+
2390+
# Runtime globals should have execute=True and RuntimeAdapter
2391+
runtime_globals = create_builtin_globals(
2392+
jinja_macros=JinjaMacroRegistry(),
2393+
jinja_globals={},
2394+
engine_adapter=mock_engine_adapter,
2395+
)
2396+
2397+
assert runtime_globals["execute"] is True
2398+
assert runtime_globals["flags"].WHICH == "run"
2399+
assert isinstance(runtime_globals["adapter"], RuntimeAdapter)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{% macro runtime_sql() %}
2+
{% if execute %}
3+
{% set result = run_query("SELECT 1 as test_col") %}
4+
{% set test_value = result.columns[0][0] %}
5+
{{ return(test_value) }}
6+
{% else %}
7+
{{ return("parse_time_placeholder") }}
8+
{% endif %}
9+
{% endmacro %}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
SELECT
2+
'{{ runtime_sql() }}' as runtime_result

0 commit comments

Comments
 (0)