You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Importing a DAG using PostgresOperator with expand(params=[...]) fails, claiming params was already specified as a partial argument, even though it wasn't.
PostgresOperator is misusing params. This argument should be renamed. Edit: Wrong operator, I was remembering something else.
Unfortunately params cannot be mapped at the time, since the value is currently needed in the scheduler, when the operator expansion is not resolved. We may change this in the future.
changed the title [-]Using `PostgresOperator`'s `params` parameter in dynamic task mapping results in error[/-][+]Task mapping against 'params'[/+]on May 30, 2022
Unfortunately params cannot be mapped at the time, since the value is currently needed in the scheduler, when the operator expansion is not resolved. We may change this in the future.
Is there a way to raise exception that will explain to the user that the chosen parameter for expand is not supported?
It’s possible, but not particularly doable unfortunately, since it’s difficult to tell apart what the user puts in when a function is called. With a function like this:
deffoo(a=None): pass
We don’t have a good way to tell if user called foo(a=None) or foo(). I’m putting together a PR to make the message slightly more vague so it’s at least not misleading, and add some documentation to explain it.
Yes, indeed. The original DAG I ran into the problem with was using different types of queries, such as DELETE FROM {table_fqn} WHERE {column} = {value};.
In that example, I can't use parameters for {table_fqn} as %(table_fqn)s will wrap the value in single quotes, resulting in an SQL syntax error. Using params gives me the plain value instead.
@hammerhead See the "Anything else" section of #24388, but you should be able to still map via parameters for the DELETE DML in a Jinja-templated SQL using {{ task.mapped_kwargs.parameters[ti.map_index].<attribute>}} as a workaround.
Assuming the desired SQL DELETE FROM {table_fqn} WHERE {column} = {value};, you could try:
Thanks, @josh-fell, the example you provided does work.
However, I couldn't apply it successfully to our implementation, in which the value of parameters is provided by another task:
@taskdefparameter_values():
# in our original implementation, this is a database query using pg_hookreturn [
{"table_fqn": "raw_metrics", "column": "ts_day", "value": "v1"},
]
sql=""" DELETE FROM {{ task.mapped_kwargs.parameters[ti.map_index].table_fqn }} WHERE {{ task.mapped_kwargs.parameters[ti.map_index].column }} = {{ task.mapped_kwargs.parameters[ti.map_index].value }};"""PostgresOperator.partial(
task_id="delete_partitions",
postgres_conn_id="cratedb_connection",
sql=sql,
).expand(parameters=parameter_values())
This fails with an error related to XCom lookups:
[2022-06-22, 07:54:34 UTC] {taskinstance.py:1889} ERROR - Task failed with exception
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/airflow/models/taskinstance.py", line 1451, in _run_raw_task
self._execute_task_with_callbacks(context, test_mode)
File "/usr/local/lib/python3.9/site-packages/airflow/models/taskinstance.py", line 1555, in _execute_task_with_callbacks
task_orig = self.render_templates(context=context)
File "/usr/local/lib/python3.9/site-packages/airflow/models/taskinstance.py", line 2212, in render_templates
rendered_task = self.task.render_template_fields(context)
File "/usr/local/lib/python3.9/site-packages/airflow/models/mappedoperator.py", line 726, in render_template_fields
self._do_render_template_fields(
File "/usr/local/lib/python3.9/site-packages/airflow/utils/session.py", line 68, in wrapper
return func(*args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/airflow/models/abstractoperator.py", line 344, in _do_render_template_fields
rendered_content = self.render_template(
File "/usr/local/lib/python3.9/site-packages/airflow/models/abstractoperator.py", line 391, in render_template
return render_template_to_string(template, context)
File "/usr/local/lib/python3.9/site-packages/airflow/utils/helpers.py", line 296, in render_template_to_string
return render_template(template, context, native=False)
File "/usr/local/lib/python3.9/site-packages/airflow/utils/helpers.py", line 291, in render_template
return "".join(nodes)
File "<template>", line 14, in root
File "/usr/local/lib/python3.9/site-packages/jinja2/sandbox.py", line 303, in getitem
return obj[argument]
File "/usr/local/lib/python3.9/site-packages/airflow/models/xcom_arg.py", line 77, in __getitem__
raise ValueError(f"XComArg only supports str lookup, received {type(item).__name__}")
ValueError: XComArg only supports str lookup, received int
Activity
uranusjr commentedon May 30, 2022
PostgresOperator is misusingEdit: Wrong operator, I was remembering something else.params. This argument should be renamed.Unfortunately
paramscannot be mapped at the time, since the value is currently needed in the scheduler, when the operator expansion is not resolved. We may change this in the future.[-]Using `PostgresOperator`'s `params` parameter in dynamic task mapping results in error[/-][+]Task mapping against 'params'[/+]eladkal commentedon May 30, 2022
Is there a way to raise exception that will explain to the user that the chosen parameter for expand is not supported?
uranusjr commentedon May 30, 2022
It’s possible, but not particularly doable unfortunately, since it’s difficult to tell apart what the user puts in when a function is called. With a function like this:
We don’t have a good way to tell if user called
foo(a=None)orfoo(). I’m putting together a PR to make the message slightly more vague so it’s at least not misleading, and add some documentation to explain it.uranusjr commentedon May 30, 2022
Oh, actually we already mention this in the documentation:
https://airflow.apache.org/docs/apache-airflow/stable/concepts/dynamic-task-mapping.html
ashb commentedon Jun 1, 2022
In this particular example the fix is to use
parametersnotparamsfor the PostgresOperator https://airflow.apache.org/docs/apache-airflow-providers-postgres/stable/_api/airflow/providers/postgres/operators/postgres/index.html#airflow.providers.postgres.operators.postgres.PostgresOperatorhammerhead commentedon Jun 1, 2022
Yes, indeed. The original DAG I ran into the problem with was using different types of queries, such as
DELETE FROM {table_fqn} WHERE {column} = {value};.In that example, I can't use
parametersfor{table_fqn}as%(table_fqn)swill wrap the value in single quotes, resulting in an SQL syntax error. Usingparamsgives me the plain value instead.See also this Stack Overflow post from another user.
Right now, I'm using a Python task as a workaround and then pass it directly to the
sqlparamer of thePostgresOperator:josh-fell commentedon Jun 11, 2022
@hammerhead See the "Anything else" section of #24388, but you should be able to still map via
parametersfor theDELETEDML in a Jinja-templated SQL using{{ task.mapped_kwargs.parameters[ti.map_index].<attribute>}}as a workaround.Assuming the desired SQL
DELETE FROM {table_fqn} WHERE {column} = {value};, you could try:Does this help?
hammerhead commentedon Jun 22, 2022
Thanks, @josh-fell, the example you provided does work.
However, I couldn't apply it successfully to our implementation, in which the value of
parametersis provided by another task:This fails with an error related to XCom lookups:
ashb commentedon Jul 26, 2022
@uranusjr Could you add this to your todo list to fix please?
Simplify data retention DAGs by using dynamic task mapping on the `pa…
Simplify data retention DAGs by using dynamic task mapping on the `pa…