-
Notifications
You must be signed in to change notification settings - Fork 16.6k
Description
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
- I agree to follow this project's Code of Conduct