Add relative start param for time filters (#7525)
* Add relative start param for time filters * Fix typo and add types to parse_human_datetime * Add relative start/end to query_object * Fix linting error
This commit is contained in:
parent
dbdb6b093a
commit
c1712e5d10
|
|
@ -51,9 +51,16 @@ class QueryObject:
|
|||
is_prequery: bool = False,
|
||||
columns: List[str] = None,
|
||||
orderby: List[List] = None,
|
||||
relative_start: str = app.config.get('DEFAULT_RELATIVE_START_TIME', 'today'),
|
||||
relative_end: str = app.config.get('DEFAULT_RELATIVE_END_TIME', 'today'),
|
||||
):
|
||||
self.granularity = granularity
|
||||
self.from_dttm, self.to_dttm = utils.get_since_until(time_range, time_shift)
|
||||
self.from_dttm, self.to_dttm = utils.get_since_until(
|
||||
relative_start=relative_start,
|
||||
relative_end=relative_end,
|
||||
time_range=time_range,
|
||||
time_shift=time_shift,
|
||||
)
|
||||
self.is_timeseries = is_timeseries
|
||||
self.time_range = time_range
|
||||
self.time_shift = utils.parse_human_timedelta(time_shift)
|
||||
|
|
|
|||
|
|
@ -599,8 +599,13 @@ BUG_REPORT_URL = None
|
|||
DOCUMENTATION_URL = None
|
||||
|
||||
# What is the Last N days relative in the time selector to:
|
||||
# 'today' means it is midnight (00:00:00) of today in the local timezone
|
||||
# 'today' means it is midnight (00:00:00) in the local timezone
|
||||
# 'now' means it is relative to the query issue time
|
||||
# If both start and end time is set to now, this will make the time
|
||||
# filter a moving window. By only setting the end time to now,
|
||||
# start time will be set to midnight, while end will be relative to
|
||||
# the query issue time.
|
||||
DEFAULT_RELATIVE_START_TIME = 'today'
|
||||
DEFAULT_RELATIVE_END_TIME = 'today'
|
||||
|
||||
# Is epoch_s/epoch_ms datetime format supposed to be considered since UTC ?
|
||||
|
|
|
|||
|
|
@ -237,14 +237,14 @@ def parse_human_datetime(s):
|
|||
# when time is not extracted, we 'reset to midnight'
|
||||
if parsed_flags & 2 == 0:
|
||||
parsed_dttm = parsed_dttm.replace(hour=0, minute=0, second=0)
|
||||
dttm = dttm_from_timtuple(parsed_dttm.utctimetuple())
|
||||
dttm = dttm_from_timetuple(parsed_dttm.utctimetuple())
|
||||
except Exception as e:
|
||||
logging.exception(e)
|
||||
raise ValueError("Couldn't parse date string [{}]".format(s))
|
||||
return dttm
|
||||
|
||||
|
||||
def dttm_from_timtuple(d: struct_time) -> datetime:
|
||||
def dttm_from_timetuple(d: struct_time) -> datetime:
|
||||
return datetime(
|
||||
d.tm_year, d.tm_mon, d.tm_mday, d.tm_hour, d.tm_min, d.tm_sec)
|
||||
|
||||
|
|
@ -306,7 +306,7 @@ def parse_human_timedelta(s: str):
|
|||
True
|
||||
"""
|
||||
cal = parsedatetime.Calendar()
|
||||
dttm = dttm_from_timtuple(datetime.now().timetuple())
|
||||
dttm = dttm_from_timetuple(datetime.now().timetuple())
|
||||
d = cal.parse(s or '', dttm)[0]
|
||||
d = datetime(d.tm_year, d.tm_mon, d.tm_mday, d.tm_hour, d.tm_min, d.tm_sec)
|
||||
return d - dttm
|
||||
|
|
@ -939,6 +939,7 @@ def get_since_until(time_range: Optional[str] = None,
|
|||
since: Optional[str] = None,
|
||||
until: Optional[str] = None,
|
||||
time_shift: Optional[str] = None,
|
||||
relative_start: Optional[str] = None,
|
||||
relative_end: Optional[str] = None) -> Tuple[datetime, datetime]:
|
||||
"""Return `since` and `until` date time tuple from string representations of
|
||||
time_range, since, until and time_shift.
|
||||
|
|
@ -965,13 +966,14 @@ def get_since_until(time_range: Optional[str] = None,
|
|||
|
||||
"""
|
||||
separator = ' : '
|
||||
relative_start = parse_human_datetime(relative_start if relative_start else 'today')
|
||||
relative_end = parse_human_datetime(relative_end if relative_end else 'today')
|
||||
common_time_frames = {
|
||||
'Last day': (relative_end - relativedelta(days=1), relative_end), # noqa: T400
|
||||
'Last week': (relative_end - relativedelta(weeks=1), relative_end), # noqa: T400
|
||||
'Last month': (relative_end - relativedelta(months=1), relative_end), # noqa: E501, T400
|
||||
'Last quarter': (relative_end - relativedelta(months=3), relative_end), # noqa: E501, T400
|
||||
'Last year': (relative_end - relativedelta(years=1), relative_end), # noqa: T400
|
||||
'Last day': (relative_start - relativedelta(days=1), relative_end), # noqa: T400
|
||||
'Last week': (relative_start - relativedelta(weeks=1), relative_end), # noqa: E501, T400
|
||||
'Last month': (relative_start - relativedelta(months=1), relative_end), # noqa: E501, T400
|
||||
'Last quarter': (relative_start - relativedelta(months=3), relative_end), # noqa: E501, T400
|
||||
'Last year': (relative_start - relativedelta(years=1), relative_end), # noqa: E501, T400
|
||||
}
|
||||
|
||||
if time_range:
|
||||
|
|
@ -988,10 +990,10 @@ def get_since_until(time_range: Optional[str] = None,
|
|||
else:
|
||||
rel, num, grain = time_range.split()
|
||||
if rel == 'Last':
|
||||
since = relative_end - relativedelta(**{grain: int(num)}) # noqa: T400
|
||||
since = relative_start - relativedelta(**{grain: int(num)}) # noqa: T400
|
||||
until = relative_end
|
||||
else: # rel == 'Next'
|
||||
since = relative_end
|
||||
since = relative_start
|
||||
until = relative_end + relativedelta(**{grain: int(num)}) # noqa: T400
|
||||
else:
|
||||
since = since or ''
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ from superset.utils.core import (
|
|||
|
||||
config = app.config
|
||||
stats_logger = config.get('STATS_LOGGER')
|
||||
relative_start = config.get('DEFAULT_RELATIVE_START_TIME', 'today')
|
||||
relative_end = config.get('DEFAULT_RELATIVE_END_TIME', 'today')
|
||||
|
||||
METRIC_KEYS = [
|
||||
|
|
@ -274,7 +275,8 @@ class BaseViz(object):
|
|||
# default order direction
|
||||
order_desc = form_data.get('order_desc', True)
|
||||
|
||||
since, until = utils.get_since_until(relative_end=relative_end,
|
||||
since, until = utils.get_since_until(relative_start=relative_start,
|
||||
relative_end=relative_end,
|
||||
time_range=form_data.get('time_range'),
|
||||
since=form_data.get('since'),
|
||||
until=form_data.get('until'))
|
||||
|
|
@ -800,7 +802,8 @@ class CalHeatmapViz(BaseViz):
|
|||
values[str(v / 10**9)] = obj.get(metric)
|
||||
data[metric] = values
|
||||
|
||||
start, end = utils.get_since_until(relative_end=relative_end,
|
||||
start, end = utils.get_since_until(relative_start=relative_start,
|
||||
relative_end=relative_end,
|
||||
time_range=form_data.get('time_range'),
|
||||
since=form_data.get('since'),
|
||||
until=form_data.get('until'))
|
||||
|
|
|
|||
|
|
@ -43,7 +43,9 @@ from superset.utils.core import (
|
|||
|
||||
|
||||
def mock_parse_human_datetime(s):
|
||||
if s in ['now', 'today']:
|
||||
if s == 'now':
|
||||
return datetime(2016, 11, 7, 9, 30, 10)
|
||||
elif s == 'today':
|
||||
return datetime(2016, 11, 7)
|
||||
elif s == 'yesterday':
|
||||
return datetime(2016, 11, 6)
|
||||
|
|
@ -51,6 +53,8 @@ def mock_parse_human_datetime(s):
|
|||
return datetime(2016, 11, 8)
|
||||
elif s == 'Last year':
|
||||
return datetime(2015, 11, 7)
|
||||
elif s == 'Last week':
|
||||
return datetime(2015, 10, 31)
|
||||
elif s == 'Last 5 months':
|
||||
return datetime(2016, 6, 7)
|
||||
elif s == 'Next 5 months':
|
||||
|
|
@ -600,7 +604,7 @@ class UtilsTestCase(unittest.TestCase):
|
|||
self.assertEqual(result, expected)
|
||||
|
||||
result = get_since_until(' : now')
|
||||
expected = None, datetime(2016, 11, 7)
|
||||
expected = None, datetime(2016, 11, 7, 9, 30, 10)
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
result = get_since_until('yesterday : tomorrow')
|
||||
|
|
@ -636,7 +640,19 @@ class UtilsTestCase(unittest.TestCase):
|
|||
self.assertEqual(result, expected)
|
||||
|
||||
result = get_since_until(time_range='5 days : now')
|
||||
expected = datetime(2016, 11, 2), datetime(2016, 11, 7)
|
||||
expected = datetime(2016, 11, 2), datetime(2016, 11, 7, 9, 30, 10)
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
result = get_since_until('Last week', relative_end='now')
|
||||
expected = datetime(2016, 10, 31), datetime(2016, 11, 7, 9, 30, 10)
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
result = get_since_until('Last week', relative_start='now')
|
||||
expected = datetime(2016, 10, 31, 9, 30, 10), datetime(2016, 11, 7)
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
result = get_since_until('Last week', relative_start='now', relative_end='now')
|
||||
expected = datetime(2016, 10, 31, 9, 30, 10), datetime(2016, 11, 7, 9, 30, 10)
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
|
|
|
|||
Loading…
Reference in New Issue