From 6a280fd185b8006a73017a0029f651291c4fb30a Mon Sep 17 00:00:00 2001 From: Anas Khan <83116240+anxkhn@users.noreply.github.com> Date: Sun, 5 Jul 2026 04:45:34 +0530 Subject: [PATCH] fix(date): import pandas locally in make_ts_exclusive make_ts_exclusive uses pd.Timedelta in its tsql branch, but pandas is only imported under TYPE_CHECKING (pandas is banned as a module-level import). Unlike its siblings make_inclusive_end and to_utc_timestamp, it never imports pandas at runtime, so make_ts_exclusive(time, dialect="tsql") raises NameError: name 'pd' is not defined. This is reachable when rendering an INCREMENTAL_BY_TIME_RANGE model with a jinja source/ref event-time filter on the tsql dialect (renderer.py), which surfaces as a ConfigError that the model could not be rendered. Add a local `import pandas as pd` inside make_ts_exclusive, mirroring the existing runtime-pandas helpers, and add a regression test covering both the tsql and non-tsql paths. Signed-off-by: Anas Khan <83116240+anxkhn@users.noreply.github.com> --- sqlmesh/utils/date.py | 2 ++ tests/utils/test_date.py | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/sqlmesh/utils/date.py b/sqlmesh/utils/date.py index bdc15125d4..5358719abe 100644 --- a/sqlmesh/utils/date.py +++ b/sqlmesh/utils/date.py @@ -344,6 +344,8 @@ def make_exclusive(time: TimeLike) -> datetime: def make_ts_exclusive(time: TimeLike, dialect: DialectType) -> datetime: + import pandas as pd + ts = to_datetime(time) if dialect == "tsql": return to_utc_timestamp(ts) - pd.Timedelta(1, unit="ns") diff --git a/tests/utils/test_date.py b/tests/utils/test_date.py index cb35a6973c..bbd5bdf63a 100644 --- a/tests/utils/test_date.py +++ b/tests/utils/test_date.py @@ -14,11 +14,13 @@ is_categorical_relative_expression, is_relative, make_inclusive, + make_ts_exclusive, to_datetime, to_time_column, to_timestamp, to_ts, to_tstz, + to_utc_timestamp, ) @@ -141,6 +143,17 @@ def test_make_inclusive_tsql(start_in, end_in, start_out, end_out, dialect) -> N ) +def test_make_ts_exclusive() -> None: + # tsql subtracts 1ns from the UTC timestamp; must not raise NameError (pd not imported) + assert make_ts_exclusive("2020-01-01 12:00:00", dialect="tsql") == to_utc_timestamp( + to_datetime("2020-01-01 12:00:00") + ) - pd.Timedelta(1, unit="ns") + # non-tsql dialects add 1 microsecond + assert make_ts_exclusive("2020-01-01 12:00:00", dialect="duckdb") == to_datetime( + "2020-01-01 12:00:00.000001" + ) + + @pytest.mark.parametrize( "expression, result", [