Skip to content

Commit

Permalink
Time grain support for unix-timestamp columns (#1093)
Browse files Browse the repository at this point in the history
* Add time grain support for time columnd in unix timestamp

* Fix datetime parsing for unix epoch

Since we've already converted unix epoch to datetime type,
we shouldn't specify 'unit' parameter in pandas.to_datetime

* Fix SQLite timestamp to datetime conversion
  • Loading branch information
yejianye authored and mistercrunch committed Sep 13, 2016
1 parent df533d3 commit 2e6b4b1
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 5 deletions.
22 changes: 22 additions & 0 deletions caravel/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,22 @@ def grains(self):
def grains_dict(self):
return {grain.name: grain for grain in self.grains()}

def epoch_to_dttm(self, ms=False):
"""Database-specific SQL to convert unix timestamp to datetime
"""
ts2date_exprs = {
'sqlite': "datetime({col}, 'unixepoch')",
'postgresql': "(timestamp 'epoch' + {col} * interval '1 second')",
'mysql': "from_unixtime({col})",
'mssql': "dateadd(S, {col}, '1970-01-01')"
}
ts2date_exprs['redshift'] = ts2date_exprs['postgresql']
ts2date_exprs['vertica'] = ts2date_exprs['postgresql']
for db_type, expr in ts2date_exprs.items():
if self.sqlalchemy_uri.startswith(db_type):
return expr.replace('{col}', '({col}/1000.0)') if ms else expr
raise Exception(_("Unable to convert unix epoch to datetime"))

def get_extra(self):
extra = {}
if self.extra:
Expand Down Expand Up @@ -795,6 +811,12 @@ def query( # sqla
# Transforming time grain into an expression based on configuration
time_grain_sqla = extras.get('time_grain_sqla')
if time_grain_sqla:
if dttm_col.python_date_format == 'epoch_s':
dttm_expr = self.database.epoch_to_dttm().format(
col=dttm_expr)
elif dttm_col.python_date_format == 'epoch_ms':
dttm_expr = self.database.epoch_to_dttm(ms=True).format(
col=dttm_expr)
udf = self.database.grains_dict().get(time_grain_sqla, '{col}')
timestamp_grain = literal_column(
udf.function.format(col=dttm_expr)).label('timestamp')
Expand Down
7 changes: 2 additions & 5 deletions caravel/viz.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,12 +172,9 @@ def get_df(self, query_obj=None):
raise Exception("No data, review your incantations!")
else:
if 'timestamp' in df.columns:
if timestamp_format == "epoch_s":
if timestamp_format in ("epoch_s", "epoch_ms"):
df.timestamp = pd.to_datetime(
df.timestamp, utc=False, unit="s")
elif timestamp_format == "epoch_ms":
df.timestamp = pd.to_datetime(
df.timestamp, utc=False, unit="ms")
df.timestamp, utc=False)
else:
df.timestamp = pd.to_datetime(
df.timestamp, utc=False, format=timestamp_format)
Expand Down

0 comments on commit 2e6b4b1

Please sign in to comment.