From 06e57bf890b74520ca6cd44c0436b18de95bc721 Mon Sep 17 00:00:00 2001 From: Maxime Beauchemin Date: Mon, 19 Oct 2015 21:43:14 -0700 Subject: [PATCH 1/2] Adding timezone offset as a datasource param --- ...2929af7925ed_tz_offsets_in_data_sources.py | 24 +++++++++++++++++++ panoramix/models.py | 7 +++--- panoramix/views.py | 16 +++++++++---- panoramix/viz.py | 5 ++-- 4 files changed, 43 insertions(+), 9 deletions(-) create mode 100644 panoramix/migrations/versions/2929af7925ed_tz_offsets_in_data_sources.py diff --git a/panoramix/migrations/versions/2929af7925ed_tz_offsets_in_data_sources.py b/panoramix/migrations/versions/2929af7925ed_tz_offsets_in_data_sources.py new file mode 100644 index 0000000000000..784657753f521 --- /dev/null +++ b/panoramix/migrations/versions/2929af7925ed_tz_offsets_in_data_sources.py @@ -0,0 +1,24 @@ +"""TZ offsets in data sources + +Revision ID: 2929af7925ed +Revises: 1e2841a4128 +Create Date: 2015-10-19 20:54:00.565633 + +""" + +# revision identifiers, used by Alembic. +revision = '2929af7925ed' +down_revision = '1e2841a4128' + +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import mysql + +def upgrade(): + op.add_column('datasources', sa.Column('offset', sa.Integer(), nullable=True)) + op.add_column('tables', sa.Column('offset', sa.Integer(), nullable=True)) + + +def downgrade(): + op.drop_column('tables', 'offset') + op.drop_column('datasources', 'offset') diff --git a/panoramix/models.py b/panoramix/models.py index cf5f82b4499bb..7cd97295ececd 100644 --- a/panoramix/models.py +++ b/panoramix/models.py @@ -11,9 +11,8 @@ from sqlalchemy import Table from sqlalchemy import create_engine, MetaData, desc, select, and_ from sqlalchemy.orm import relationship -from sqlalchemy.sql import table, literal_column, text, column +from sqlalchemy.sql import table, literal_column, text from sqlalchemy.sql.elements import ColumnClause -from flask import request from copy import deepcopy, copy from collections import namedtuple @@ -201,7 +200,7 @@ def get_table(self, table_name): autoload_with=self.get_sqla_engine()) -class SqlaTable(Model, Queryable, AuditMixinNullable): +class SqlaTable(Model, Queryable): type = "table" __tablename__ = 'tables' @@ -212,6 +211,7 @@ class SqlaTable(Model, Queryable, AuditMixinNullable): database_id = Column(Integer, ForeignKey('dbs.id'), nullable=False) database = relationship( 'Database', backref='tables', foreign_keys=[database_id]) + offset = Column(Integer, default=0) baselink = "tableview" @@ -655,6 +655,7 @@ class Datasource(Model, AuditMixin, Queryable): String(250), ForeignKey('clusters.cluster_name')) cluster = relationship( 'Cluster', backref='datasources', foreign_keys=[cluster_name]) + offset = Column(Integer, default=0) @property def metrics_combo(self): diff --git a/panoramix/views.py b/panoramix/views.py index 9a36c1cd11677..da5dbc3307717 100644 --- a/panoramix/views.py +++ b/panoramix/views.py @@ -126,10 +126,14 @@ class DatabaseView(PanoramixModelView, DeleteMixin): class TableView(PanoramixModelView, DeleteMixin): datamodel = SQLAInterface(models.SqlaTable) list_columns = ['table_link', 'database'] - add_columns = ['table_name', 'database', 'default_endpoint'] + add_columns = ['table_name', 'database', 'default_endpoint', 'offset'] edit_columns = [ - 'table_name', 'database', 'main_dttm_col', 'default_endpoint'] + 'table_name', 'database', 'main_dttm_col', 'default_endpoint', + 'offset'] related_views = [TableColumnInlineView, SqlMetricInlineView] + description_columns = { + 'offset': "Timezone offset (in hours) for this datasource" + } def post_add(self, table): try: @@ -219,13 +223,17 @@ class DashboardModelView(PanoramixModelView, DeleteMixin): class DatasourceModelView(PanoramixModelView, DeleteMixin): datamodel = SQLAInterface(models.Datasource) list_columns = [ - 'datasource_link', 'cluster', 'owner', 'is_featured', 'is_hidden'] + 'datasource_link', 'cluster', 'owner', 'is_featured', 'is_hidden', + 'offset'] related_views = [ColumnInlineView, MetricInlineView] edit_columns = [ 'datasource_name', 'cluster', 'description', 'owner', - 'is_featured', 'is_hidden', 'default_endpoint'] + 'is_featured', 'is_hidden', 'default_endpoint', 'offset'] page_size = 100 base_order = ('datasource_name', 'asc') + description_columns = { + 'offset': "Timezone offset (in hours) for this datasource" + } def post_add(self, datasource): datasource.generate_metrics() diff --git a/panoramix/viz.py b/panoramix/viz.py index 4c766f65447e4..d45a40097f325 100644 --- a/panoramix/viz.py +++ b/panoramix/viz.py @@ -1,6 +1,5 @@ from collections import OrderedDict, defaultdict -from copy import copy -from datetime import datetime +from datetime import datetime, timedelta import json import uuid @@ -110,6 +109,8 @@ def get_df(self, query_obj=None): else: if 'timestamp' in df.columns: df.timestamp = pd.to_datetime(df.timestamp) + if self.datasource.offset: + df.timestamp += timedelta(hours=self.datasource.offset) return df @property From a7fca30010e0878e3d4573bf86a45b3a1e5b030d Mon Sep 17 00:00:00 2001 From: Maxime Beauchemin Date: Mon, 19 Oct 2015 21:46:10 -0700 Subject: [PATCH 2/2] Tweaks --- panoramix/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/panoramix/models.py b/panoramix/models.py index 7cd97295ececd..a55e56a3bcd5a 100644 --- a/panoramix/models.py +++ b/panoramix/models.py @@ -200,7 +200,7 @@ def get_table(self, table_name): autoload_with=self.get_sqla_engine()) -class SqlaTable(Model, Queryable): +class SqlaTable(Model, Queryable, AuditMixinNullable): type = "table" __tablename__ = 'tables' @@ -637,7 +637,7 @@ def refresh_datasources(self): Datasource.sync_to_db(datasource, self) -class Datasource(Model, AuditMixin, Queryable): +class Datasource(Model, AuditMixinNullable, Queryable): type = "druid" baselink = "datasourcemodelview"