Skip to content

SqlExecuteQueryOperator template_fields order swap #62565

@vaefremov95

Description

@vaefremov95

Description

Swap parameters and sql in SqlExecuteQueryOperator template_fileds.

Use case/motivation

Hi!
I couldn’t find any related issues, so I’m creating this one.

In my pipelines, I often use dozens of SQL queries that depend on a single variable, such as {{ ds }}. It is crucial that this variable is templated to ensure correct backfilling. Instead of repeating it in every query, I would like to initialize it once and then reuse it across operators.

date = '{{ ds }}'

operator_1 = SqlExecuteQueryOperator(),
operator_2 = SqlExecuteQueryOperator(),
etc

Currently, I dont know any easy way to achieve this behavior.

I cannot pass variable via params.

operator_1 = SqlExecuteQueryOperator(
    sql = "select '{{ params.date }}'"
    params={'date': date}
)

Params filed is not templated, so the query ends up as select '{{ ds }}' which leads to a failure.

I also cannot pass the variable via parameters

operator_1 = SqlExecuteQueryOperator(
    sql = 'select * from "test%(date)s"'
    parameters={'date': date}
)

First, its not properly rendered in UI, query stays the same select * from test%(date)s.
More importantly, parameters are passed with quotes. This breaks queries where quotes are not needed.
For example, if I need to use a parameter in a table name, the resulting query becomes select * from "test'2025-01-01'" and fails with error.

I also tried passing variable in parameters like this

operator_1 = SqlExecuteQueryOperator(
    sql = 'select * from "test{{ task.parameters.date }}"
    parameters={'date': date}
)

This results in a Jinja exception None has no attribute
As I understand it, this happens because parameters are rendered after sql.
template_fields: Sequence[str] = ("sql", "parameters", *BaseSQLOperator.template_fields)

So sql has no visibility of parameters in the template context.
However, if we swap the order like this:
template_fields: Sequence[str] = ("parameters", "sql", *BaseSQLOperator.template_fields)
it all begins to work.

I have tested query with this change in my local env:

operator_1 = SqlExecuteQueryOperator(
    sql = 'select * from "test{{ task.parameters.date }}"
    parameters={'date': date}
)

Query correctly renders to: select * from "test2025-01-01" and no exception is raised.

Therefore, I would like to propose swapping parameters and sql in template_fields for SqlExecuteQueryOperator. This would simplify the construction of pipelines in cases like this.

Please let me know if I’m misunderstanding something or overlooking an existing solution.

If this approach is acceptable, I would be happy to open a PR.

Related issues

No response

Are you willing to submit a PR?

  • Yes I am willing to submit a PR!

Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions