Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:TobikoData Sqlmesh Context Render Evaluate Fetchdf

From Leeroopedia


Knowledge Sources
Domains Data_Engineering, Model_Development, Data_Quality
Last Updated 2026-02-07 00:00 GMT

Overview

Concrete query rendering, execution, and data retrieval methods for model exploration provided by SQLMesh.

Description

SQLMesh provides three complementary methods for data exploration during development: Context.render expands a model's query with all macros and references resolved, returning the final SQL expression without executing it; Context.evaluate executes a model's query against the database for a specific time interval and returns the results as a DataFrame; Context.fetchdf executes arbitrary SQL queries and returns results as a DataFrame.

These methods form a complete toolkit for iterative model development. render helps debug macro expansion and understand generated SQL. evaluate validates model logic with real data and specific time boundaries, respecting incremental model semantics. fetchdf enables ad-hoc exploration of source tables and testing of query fragments. Together, they provide visibility into the transformation pipeline at multiple abstraction levels.

Usage

Use render when debugging macro issues, verifying dependency resolution, or understanding what SQL will execute. Use evaluate when testing model logic with production data, validating incremental processing, or generating sample outputs. Use fetchdf for ad-hoc queries, exploring source data, or debugging specific data issues outside the model framework.

Code Reference

Source Location

  • Repository: sqlmesh
  • File: sqlmesh/core/context.py
    • render: Lines 1096-1119
    • evaluate: Lines 1165-1184
    • fetchdf: Lines 236-248

Signature

# Method 1: render
def render(
    self,
    model_or_snapshot: ModelOrSnapshot,
    *,
    start: t.Optional[TimeLike] = None,
    end: t.Optional[TimeLike] = None,
    execution_time: t.Optional[TimeLike] = None,
    expand: t.Union[bool, t.Iterable[str]] = False,
    **kwargs: t.Any,
) -> exp.Expression

# Method 2: evaluate
def evaluate(
    self,
    model_or_snapshot: ModelOrSnapshot,
    start: TimeLike,
    end: TimeLike,
    execution_time: TimeLike,
    limit: t.Optional[int] = None,
    **kwargs: t.Any,
) -> DF

# Method 3: fetchdf
def fetchdf(
    self,
    query: t.Union[exp.Expression, str],
    quote_identifiers: bool = False
) -> pd.DataFrame

Import

from sqlmesh import Context

context = Context()

I/O Contract

Inputs

render method:

Name Type Required Description
model_or_snapshot ModelOrSnapshot Yes Model object, model name, or snapshot to render
start TimeLike No Start of time interval for incremental models
end TimeLike No End of time interval for incremental models
execution_time TimeLike No Execution timestamp reference (default: now)
expand bool or Iterable[str] No Whether to inline upstream model queries (True=all, list=specific models)

evaluate method:

Name Type Required Description
model_or_snapshot ModelOrSnapshot Yes Model object, model name, or snapshot to evaluate
start TimeLike Yes Start of time interval to evaluate
end TimeLike Yes End of time interval to evaluate
execution_time TimeLike Yes Execution timestamp reference
limit int No Row limit for sampling results

fetchdf method:

Name Type Required Description
query Expression or str Yes SQL query to execute
quote_identifiers bool No Whether to quote all identifiers (default: False)

Outputs

Method Return Type Description
render exp.Expression SQLGlot Expression object representing the rendered SQL
evaluate DF DataFrame with query results (Pandas or PySpark depending on engine)
fetchdf pd.DataFrame Pandas DataFrame with query results

Usage Examples

Rendering Model SQL

from sqlmesh import Context

context = Context()

# Render model SQL with macro expansion
rendered = context.render(
    "my_schema.my_model",
    start="2024-01-01",
    end="2024-01-31",
    execution_time="2024-02-01"
)

# View the generated SQL
print(rendered.sql(pretty=True))

Expanding Upstream References

# Render with all upstream models inlined
expanded_query = context.render(
    "my_schema.final_model",
    start="2024-01-01",
    end="2024-01-01",
    expand=True  # Inline all upstream model queries
)

# Or expand only specific models
partial_expand = context.render(
    "my_schema.final_model",
    start="2024-01-01",
    end="2024-01-01",
    expand=["my_schema.intermediate_model"]  # Only inline this model
)

print(partial_expand.sql(pretty=True))

Evaluating Model with Sample Data

# Execute model and get results
results = context.evaluate(
    "my_schema.revenue_summary",
    start="2024-01-01",
    end="2024-01-07",
    execution_time="2024-01-08",
    limit=100  # Sample first 100 rows
)

# Inspect results
print(f"Rows returned: {len(results)}")
print(results.head())

# Validate business logic
assert results['revenue'].sum() > 0
assert results['revenue'].isnull().sum() == 0

Ad-hoc Query Execution

# Execute arbitrary SQL for exploration
df = context.fetchdf("""
    SELECT
        date,
        COUNT(*) as transaction_count,
        SUM(amount) as total_amount
    FROM raw.transactions
    WHERE date BETWEEN '2024-01-01' AND '2024-01-31'
    GROUP BY date
    ORDER BY date
""")

print(df)

Combined Workflow for Development

# Step 1: Render to verify SQL looks correct
rendered = context.render(
    "my_schema.new_model",
    start="2024-01-01",
    end="2024-01-01"
)
print("Generated SQL:")
print(rendered.sql(pretty=True))

# Step 2: Evaluate to test with real data
results = context.evaluate(
    "my_schema.new_model",
    start="2024-01-01",
    end="2024-01-01",
    execution_time="2024-01-02",
    limit=10
)
print("\nSample results:")
print(results)

# Step 3: Query upstream source for comparison
source_data = context.fetchdf("""
    SELECT * FROM raw.source_table
    WHERE date = '2024-01-01'
    LIMIT 10
""")
print("\nUpstream source data:")
print(source_data)

# Step 4: Validate transformation logic
assert len(results) <= len(source_data), "Model should not create rows"

Debugging Macro Expansion

# Compare rendered SQL with and without macro context
rendered_dev = context.render(
    "my_schema.model_with_macros",
    start="2024-01-01",
    end="2024-01-01"
)

# Check that macros expanded correctly
sql_text = rendered_dev.sql(pretty=True)
assert "@" not in sql_text, "Macro variables should be expanded"

print("Macros expanded successfully:")
print(sql_text)

Related Pages

Implements Principle

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment