fix: Bad date type in email text report for table chart (#20119)

* fix bad date type in email text report for table chart

* fix test, pylint issue

* add test case for date type
This commit is contained in:
Smart-Codi
2022-07-07 18:31:50 +01:00
committed by GitHub
parent 962252030b
commit e7b965a3b2
2 changed files with 74 additions and 2 deletions

View File

@@ -14,6 +14,7 @@
# KIND, either express or implied. See the License for the # KIND, either express or implied. See the License for the
# specific language governing permissions and limitations # specific language governing permissions and limitations
# under the License. # under the License.
import logging
import re import re
import urllib.request import urllib.request
from typing import Any, Dict, Optional from typing import Any, Dict, Optional
@@ -23,6 +24,10 @@ import numpy as np
import pandas as pd import pandas as pd
import simplejson import simplejson
from superset.utils.core import GenericDataType
logger = logging.getLogger(__name__)
negative_number_re = re.compile(r"^-[0-9.]+$") negative_number_re = re.compile(r"^-[0-9.]+$")
# This regex will match if the string starts with: # This regex will match if the string starts with:
@@ -102,11 +107,22 @@ def get_chart_dataframe(
return None return None
result = simplejson.loads(content.decode("utf-8")) result = simplejson.loads(content.decode("utf-8"))
# need to convert float value to string to show full long number # need to convert float value to string to show full long number
pd.set_option("display.float_format", lambda x: str(x)) pd.set_option("display.float_format", lambda x: str(x))
df = pd.DataFrame.from_dict(result["result"][0]["data"]) df = pd.DataFrame.from_dict(result["result"][0]["data"])
try:
# if any column type is equal to 2, need to convert data into
# datetime timestamp for that column.
if GenericDataType.TEMPORAL in result["result"][0]["coltypes"]:
for i in range(len(result["result"][0]["coltypes"])):
if result["result"][0]["coltypes"][i] == GenericDataType.TEMPORAL:
df[result["result"][0]["colnames"][i]] = df[
result["result"][0]["colnames"][i]
].astype("datetime64[ms]")
except BaseException as err:
logger.error(err)
# rebuild hierarchical columns and index # rebuild hierarchical columns and index
df.columns = pd.MultiIndex.from_tuples( df.columns = pd.MultiIndex.from_tuples(
tuple(colname) if isinstance(colname, list) else (colname,) tuple(colname) if isinstance(colname, list) else (colname,)

View File

@@ -16,7 +16,7 @@
# under the License. # under the License.
import json import json
from contextlib import contextmanager from contextlib import contextmanager
from datetime import datetime, timedelta from datetime import datetime, timedelta, timezone
from typing import Any, Dict, List, Optional from typing import Any, Dict, List, Optional
from unittest.mock import Mock, patch from unittest.mock import Mock, patch
from uuid import uuid4 from uuid import uuid4
@@ -960,6 +960,8 @@ def test_email_chart_report_schedule_with_text(
mock_open.return_value = response mock_open.return_value = response
mock_urlopen.return_value = response mock_urlopen.return_value = response
mock_urlopen.return_value.getcode.return_value = 200 mock_urlopen.return_value.getcode.return_value = 200
# test without date type.
response.read.return_value = json.dumps( response.read.return_value = json.dumps(
{ {
"result": [ "result": [
@@ -971,6 +973,7 @@ def test_email_chart_report_schedule_with_text(
}, },
"colnames": [("t1",), ("t2",), ("t3__sum",)], "colnames": [("t1",), ("t2",), ("t3__sum",)],
"indexnames": [(0,), (1,)], "indexnames": [(0,), (1,)],
"coltypes": [1, 1],
}, },
], ],
} }
@@ -1011,6 +1014,59 @@ def test_email_chart_report_schedule_with_text(
# Assert logs are correct # Assert logs are correct
assert_log(ReportState.SUCCESS) assert_log(ReportState.SUCCESS)
# test with date type.
dt = datetime(2022, 1, 1).replace(tzinfo=timezone.utc)
ts = datetime.timestamp(dt) * 1000
response.read.return_value = json.dumps(
{
"result": [
{
"data": {
"t1": {0: "c11", 1: "c21"},
"t2__date": {0: ts, 1: ts},
"t3__sum": {0: "c13", 1: "c23"},
},
"colnames": [("t1",), ("t2__date",), ("t3__sum",)],
"indexnames": [(0,), (1,)],
"coltypes": [1, 2],
},
],
}
).encode("utf-8")
with freeze_time("2020-01-01T00:00:00Z"):
AsyncExecuteReportScheduleCommand(
TEST_ID, create_report_email_chart_with_text.id, datetime.utcnow()
).run()
# assert that the data is embedded correctly
table_html = """<table border="1" class="dataframe">
<thead>
<tr>
<th></th>
<th>t1</th>
<th>t2__date</th>
<th>t3__sum</th>
</tr>
</thead>
<tbody>
<tr>
<th>0</th>
<td>c11</td>
<td>2022-01-01</td>
<td>c13</td>
</tr>
<tr>
<th>1</th>
<td>c21</td>
<td>2022-01-01</td>
<td>c23</td>
</tr>
</tbody>
</table>"""
assert table_html in email_mock.call_args[0][2]
@pytest.mark.usefixtures( @pytest.mark.usefixtures(
"load_birth_names_dashboard_with_slices", "create_report_email_dashboard" "load_birth_names_dashboard_with_slices", "create_report_email_dashboard"