Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Ensure the reporting framework handles charts with no data #23585

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions superset/charts/post_processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,14 +328,19 @@ def apply_post_process(
if query["result_format"] not in (rf.value for rf in ChartDataResultFormat):
raise Exception(f"Result format {query['result_format']} not supported")

if not query["data"]:
data = query["data"]

if isinstance(data, str):
data = data.strip()
Copy link
Member Author

@john-bodley john-bodley Apr 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prevents the pandas.errors.EmptyDataError: No columns to parse from file error when query["data"] is \n—invoked via the/api/v1/chart/<pk>/data/?format=csv&type=post_processed endpoint.


if not data:
# do not try to process empty data
continue

if query["result_format"] == ChartDataResultFormat.JSON:
df = pd.DataFrame.from_dict(query["data"])
df = pd.DataFrame.from_dict(data)
elif query["result_format"] == ChartDataResultFormat.CSV:
df = pd.read_csv(StringIO(query["data"]))
df = pd.read_csv(StringIO(data))

# convert all columns to verbose (label) name
if datasource:
Expand Down
3 changes: 3 additions & 0 deletions superset/utils/csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ def get_chart_dataframe(
pd.set_option("display.float_format", lambda x: str(x))
df = pd.DataFrame.from_dict(result["result"][0]["data"])

if df.empty:
return None

try:
# if any column type is equal to 2, need to convert data into
# datetime timestamp for that column.
Expand Down
11 changes: 6 additions & 5 deletions tests/unit_tests/charts/test_post_processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
import json

import pandas as pd
import pytest
from flask_babel import lazy_gettext as _
from numpy import True_
from pytest import raises
from sqlalchemy.orm.session import Session

from superset.charts.post_processing import apply_post_process, pivot_df, table
Expand Down Expand Up @@ -1389,7 +1389,7 @@ def test_apply_post_process_without_result_format():
result = {"queries": [{"result_format": "foo"}]}
form_data = {"viz_type": "pivot_table"}

with raises(Exception) as ex:
with pytest.raises(Exception) as ex:
apply_post_process(result, form_data)

assert ex.match("Result format foo not supported") == True
Expand Down Expand Up @@ -1659,12 +1659,13 @@ def test_apply_post_process_csv_format_empty_string():
}


def test_apply_post_process_csv_format_no_data():
@pytest.mark.parametrize("data", [None, "", "\n"])
def test_apply_post_process_csv_format_no_data(data):
"""
It should be able to process csv results with no data
"""

result = {"queries": [{"result_format": ChartDataResultFormat.CSV, "data": None}]}
result = {"queries": [{"result_format": ChartDataResultFormat.CSV, "data": data}]}
form_data = {
"datasource": "19__table",
"viz_type": "pivot_table_v2",
Expand Down Expand Up @@ -1726,7 +1727,7 @@ def test_apply_post_process_csv_format_no_data():
}

assert apply_post_process(result, form_data) == {
"queries": [{"result_format": ChartDataResultFormat.CSV, "data": None}]
"queries": [{"result_format": ChartDataResultFormat.CSV, "data": data}]
}


Expand Down