Repository navigation
Description
Apache Airflow version
2.6.1
What happened
When i use do_xcom_push=True in DatabricksSqlOperator the an exception with following stack trace is thrown:
[2023-06-06, 08:52:24 UTC] {sql.py:375} INFO - Running statement: SELECT cast(max(id) as STRING) FROM prod.unified.sessions, parameters: None
[2023-06-06, 08:52:25 UTC] {taskinstance.py:1824} ERROR - Task failed with exception
Traceback (most recent call last):
File "/home/airflow/.local/lib/python3.10/site-packages/airflow/utils/session.py", line 73, in wrapper
return func(*args, **kwargs)
File "/home/airflow/.local/lib/python3.10/site-packages/airflow/models/taskinstance.py", line 2354, in xcom_push
XCom.set(
File "/home/airflow/.local/lib/python3.10/site-packages/airflow/utils/session.py", line 73, in wrapper
return func(*args, **kwargs)
File "/home/airflow/.local/lib/python3.10/site-packages/airflow/models/xcom.py", line 237, in set
value = cls.serialize_value(
File "/home/airflow/.local/lib/python3.10/site-packages/airflow/models/xcom.py", line 632, in serialize_value
return json.dumps(value, cls=XComEncoder).encode("UTF-8")
File "/usr/local/lib/python3.10/json/__init__.py", line 238, in dumps
**kw).encode(obj)
File "/home/airflow/.local/lib/python3.10/site-packages/airflow/utils/json.py", line 102, in encode
o = self.default(o)
File "/home/airflow/.local/lib/python3.10/site-packages/airflow/utils/json.py", line 91, in default
return serialize(o)
File "/home/airflow/.local/lib/python3.10/site-packages/airflow/serialization/serde.py", line 144, in serialize
return encode(classname, version, serialize(data, depth + 1))
File "/home/airflow/.local/lib/python3.10/site-packages/airflow/serialization/serde.py", line 123, in serialize
return [serialize(d, depth + 1) for d in o]
File "/home/airflow/.local/lib/python3.10/site-packages/airflow/serialization/serde.py", line 123, in <listcomp>
return [serialize(d, depth + 1) for d in o]
File "/home/airflow/.local/lib/python3.10/site-packages/airflow/serialization/serde.py", line 132, in serialize
qn = qualname(o)
File "/home/airflow/.local/lib/python3.10/site-packages/airflow/utils/module_loading.py", line 47, in qualname
return f"{o.__module__}.{o.__name__}"
File "/home/airflow/.local/lib/python3.10/site-packages/databricks/sql/types.py", line 161, in __getattr__
raise AttributeError(item)
AttributeError: __name__. Did you mean: '__ne__'?
What you think should happen instead
In _process_output() if self._output_path is False a list of tuples is returned:
def _process_output(self, results: list[Any], descriptions: list[Sequence[Sequence] | None]) -> list[Any]:
if not self._output_path:
return list(zip(descriptions, results))
I suspect this breaks the serialization somehow which might be related to my own meta database(postgres).
Replacing the Databricks SQL Operator with simple PythonOperator and DatabricksSqlHook works just fine:
def get_max_id(ti):
hook = DatabricksSqlHook(databricks_conn_id=databricks_sql_conn_id, sql_endpoint_name='sql_endpoint')
sql = "SELECT cast(max(id) as STRING) FROM prod.unified.sessions"
return str(hook.get_first(sql)[0])
How to reproduce
get_max_id_task = DatabricksSqlOperator(
databricks_conn_id=databricks_sql_conn_id,
sql_endpoint_name='sql_endpoint',
task_id='get_max_id',
sql="SELECT cast(max(id) as STRING) FROM prod.unified.sessions",
do_xcom_push=True
)
Operating System
Debian GNU/Linux 11 (bullseye) docker image, python 3.10
Versions of Apache Airflow Providers
apache-airflow-providers-common-sql==1.5.1
databricks-sql-connector==2.5.2
apache-airflow-providers-databricks==4.2.0
Deployment
Docker-Compose
Deployment details
Using extended Airflow image, LocalExecutor, Postgres 13 meta db as container in the same stack.
docker-compose version 1.29.2, build 5becea4c
Docker version 23.0.5, build bc4487a
Anything else
No response
Are you willing to submit PR?
- Yes I am willing to submit a PR!
Code of Conduct
- I agree to follow this project's Code of Conduct
Activity
phanikumv commentedon Jun 7, 2023
@Stormhand can you please mention what is the value that you are trying to cast ? Basically I need the value of
max(id)which you are tryting to cast to STRING so that I can try to reproduce this on my end?Stormhand commentedon Jun 7, 2023
Its 32bit integer. Then i tried to cast it as string but didnt work.
BTW. It started failing after i updated to 2.6.1 from 2.6.0
phanikumv commentedon Jun 7, 2023
Yes @Stormhand I was able to reproduce this issue. I am getting this error on 2.6.1 with the below DAG
cc @jedcunningham @potiuk
potiuk commentedon Jun 7, 2023
@phanikumv, It looks like databricks returns a description which is both callable and has no
__name__defined and theserdeof ours does not handle this well. Since you have the environment ready - Maybe you can inspect and print the actual type of the object returned there ? That would help wit determining a fix.phanikumv commentedon Jun 7, 2023
You are correct @potiuk , it is coming in as a Row object,
It contains
__module__but not__name__Below is the output when I did a
dir(o)hussein-awala commentedon Jun 7, 2023
I think we should close it as duplication of #31499, @potiuk wdyt?
@Stormhand can you try this solution:
Stormhand commentedon Jun 7, 2023
What's the point? Using the hook as in the original post is way shorter and easier.
Edit: or you mean just for the test?
hussein-awala commentedon Jun 7, 2023
Here is the full comment:
If we cannot serialize the returned objects from the Databricks cursor because of a limitation in the databricks lib, we need to find a workaround for Databricks provider and not change our serialization strategy, for that I suggest this solution before opening a PR.
So it is not just for testing, if you test it and you find that it fixes the issue, you can open a PR to fix it in the Airflow Databricks provider.
Better error message when serializing callable without name
potiuk commentedon Jun 7, 2023
Yes we should not change our strategy, and yes we should make a change in the provider, however I think we can also improve the error message in this case (PR here - just worked on it #31778)
Better error message when serializing callable without name (#31778)
Fix Databricks SQL operator serialization
potiuk commentedon Jun 7, 2023
I think #31780 hould fix it @Stormhand @phanikumv - is it possible you test it on your system by patching the code ? That would help to validate if this is ok (it works in unit tests).
phanikumv commentedon Jun 8, 2023
Yes #31780 fixes the issue,I have mentioned the test results here #31780 (review)
Fix Databricks SQL operator serialization (#31780)