diff --git a/superset/assets/src/explore/controls.jsx b/superset/assets/src/explore/controls.jsx index f2f12e03080..0900d2cf1ba 100644 --- a/superset/assets/src/explore/controls.jsx +++ b/superset/assets/src/explore/controls.jsx @@ -898,7 +898,7 @@ export const controls = { time_grain_sqla: { type: 'SelectControl', label: t('Time Grain'), - default: control => control.choices && control.choices.length ? control.choices[0][0] : null, + default: 'P1D', description: t('The time granularity for the visualization. This ' + 'applies a date transformation to alter ' + 'your time column and defines a new time granularity. ' + diff --git a/superset/assets/src/explore/visTypes.jsx b/superset/assets/src/explore/visTypes.jsx index 5df65dfd9e1..69b129794ee 100644 --- a/superset/assets/src/explore/visTypes.jsx +++ b/superset/assets/src/explore/visTypes.jsx @@ -948,9 +948,6 @@ export const visTypes = { metrics: { validators: [], }, - time_grain_sqla: { - default: null, - }, }, }, diff --git a/superset/dataframe.py b/superset/dataframe.py index 447aa683df5..834f1180474 100644 --- a/superset/dataframe.py +++ b/superset/dataframe.py @@ -132,13 +132,18 @@ class SupersetDataFrame(object): continue return 100 * success / total - @classmethod - def is_date(cls, dtype): - if dtype and dtype.name: - return any([ - dtype.name.lower().startswith(s) - for s in ['date', 'time'] - ]) + @staticmethod + def is_date(np_dtype, db_type_str): + + def looks_daty(s): + if isinstance(s, basestring): + return any([s.lower().startswith(ss) for ss in ('time', 'date')]) + return False + + if looks_daty(db_type_str): + return True + if np_dtype and np_dtype.name and looks_daty(np_dtype.name): + return True return False @classmethod @@ -176,19 +181,19 @@ class SupersetDataFrame(object): if sample_size: sample = self.df.sample(sample_size) for col in self.df.dtypes.keys(): - col_db_type = ( + db_type_str = ( self._type_dict.get(col) or self.db_type(self.df.dtypes[col]) ) column = { 'name': col, 'agg': self.agg_func(self.df.dtypes[col], col), - 'type': col_db_type, - 'is_date': self.is_date(self.df.dtypes[col]), + 'type': db_type_str, + 'is_date': self.is_date(self.df.dtypes[col], db_type_str), 'is_dim': self.is_dimension(self.df.dtypes[col], col), } - if column['type'] in ('OBJECT', None): + if not db_type_str or db_type_str.upper() == 'OBJECT': v = sample[col].iloc[0] if not sample[col].empty else None if isinstance(v, basestring): column['type'] = 'STRING' diff --git a/tests/dataframe_test.py b/tests/dataframe_test.py index c5ea504345b..b52b9508abb 100644 --- a/tests/dataframe_test.py +++ b/tests/dataframe_test.py @@ -122,10 +122,14 @@ class SupersetDataFrameTestCase(SupersetTestCase): def test_is_date(self): f = SupersetDataFrame.is_date - self.assertEquals(f(np.dtype('M')), True) + self.assertEquals(f(np.dtype('M'), ''), True) + self.assertEquals(f(np.dtype('f'), 'DATETIME'), True) + self.assertEquals(f(np.dtype('i'), 'TIMESTAMP'), True) + self.assertEquals(f(None, 'DATETIME'), True) + self.assertEquals(f(None, 'TIMESTAMP'), True) - self.assertEquals(f(None), False) - self.assertEquals(f(np.dtype(np.int32)), False) + self.assertEquals(f(None, ''), False) + self.assertEquals(f(np.dtype(np.int32), ''), False) def test_dedup_with_data(self): data = [