superset-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From maximebeauche...@apache.org
Subject [incubator-superset] branch master updated: Filtering out SQLLab views out of table list view by default (#4746)
Date Thu, 12 Apr 2018 20:52:55 GMT
This is an automated email from the ASF dual-hosted git repository.

maximebeauchemin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
     new b043590  Filtering out SQLLab views out of table list view by default (#4746)
b043590 is described below

commit b04359003ec8ea0ecae55166941b6589528592bd
Author: Maxime Beauchemin <maximebeauchemin@gmail.com>
AuthorDate: Thu Apr 12 13:52:47 2018 -0700

    Filtering out SQLLab views out of table list view by default (#4746)
    
    * Filtering out SQLLab views out of table list view by default
    
    This adds a `is_sqllab_view` flag in the "tables" table, and makes the
    filters those out in the Tables list view.
    
    The filter showing on top may be a bit confusing, but certainly less
    than seeing lots of user generated views.
    
    * flake
    
    * Addressing comments
---
 .../javascripts/addSlice/AddSliceContainer.jsx     | 86 ++++++++++++----------
 superset/connectors/base/models.py                 |  4 +
 superset/connectors/connector_registry.py          |  6 +-
 superset/connectors/sqla/models.py                 |  5 ++
 superset/connectors/sqla/views.py                  | 21 ++++--
 .../versions/130915240929_is_sqllab_viz_flow.py    | 54 ++++++++++++++
 superset/views/core.py                             |  1 +
 7 files changed, 129 insertions(+), 48 deletions(-)

diff --git a/superset/assets/javascripts/addSlice/AddSliceContainer.jsx b/superset/assets/javascripts/addSlice/AddSliceContainer.jsx
index 0516934..6b1f5e7 100644
--- a/superset/assets/javascripts/addSlice/AddSliceContainer.jsx
+++ b/superset/assets/javascripts/addSlice/AddSliceContainer.jsx
@@ -1,6 +1,6 @@
 import React from 'react';
 import PropTypes from 'prop-types';
-import { Button, Panel, Grid, Row, Col } from 'react-bootstrap';
+import { Button, Panel } from 'react-bootstrap';
 import Select from 'react-virtualized-select';
 import visTypes from '../explore/stores/visTypes';
 import { t } from '../locales';
@@ -12,6 +12,8 @@ const propTypes = {
   })).isRequired,
 };
 
+const styleSelectWidth = { width: 300 };
+
 export default class AddSliceContainer extends React.PureComponent {
   constructor(props) {
     super(props);
@@ -55,44 +57,50 @@ export default class AddSliceContainer extends React.PureComponent {
     return (
       <div className="container">
         <Panel header={<h3>{t('Create a new slice')}</h3>}>
-          <Grid>
-            <Row>
-              <Col xs={12} sm={6}>
-                <div>
-                  <p>{t('Choose a datasource')}</p>
-                  <Select
-                    clearable={false}
-                    name="select-datasource"
-                    onChange={this.changeDatasource.bind(this)}
-                    options={this.props.datasources}
-                    placeholder={t('Choose a datasource')}
-                    value={this.state.datasourceValue}
-                  />
-                </div>
-                <br />
-                <div>
-                  <p>{t('Choose a visualization type')}</p>
-                  <Select
-                    clearable={false}
-                    name="select-vis-type"
-                    onChange={this.changeVisType.bind(this)}
-                    options={this.vizTypeOptions}
-                    placeholder={t('Choose a visualization type')}
-                    value={this.state.visType}
-                  />
-                </div>
-                <br />
-                <Button
-                  bsStyle="primary"
-                  disabled={this.isBtnDisabled()}
-                  onClick={this.gotoSlice.bind(this)}
-                >
-                  {t('Create new slice')}
-                </Button>
-                <br /><br />
-              </Col>
-            </Row>
-          </Grid>
+          <div>
+            <p>{t('Choose a datasource')}</p>
+            <div style={styleSelectWidth}>
+              <Select
+                clearable={false}
+                style={styleSelectWidth}
+                name="select-datasource"
+                onChange={this.changeDatasource.bind(this)}
+                options={this.props.datasources}
+                placeholder={t('Choose a datasource')}
+                value={this.state.datasourceValue}
+                width={200}
+              />
+            </div>
+            <p className="text-muted">
+              {t(
+                'If the datasource your are looking for is not ' +
+                'available in the list, ' +
+                'follow the instructions on the how to add it on the ')}
+              <a href="http://superset.apache.org/tutorial.html">{t('Superset tutorial')}</a>
+            </p>
+          </div>
+          <br />
+          <div>
+            <p>{t('Choose a visualization type')}</p>
+            <Select
+              clearable={false}
+              name="select-vis-type"
+              style={styleSelectWidth}
+              onChange={this.changeVisType.bind(this)}
+              options={this.vizTypeOptions}
+              placeholder={t('Choose a visualization type')}
+              value={this.state.visType}
+            />
+          </div>
+          <br />
+          <Button
+            bsStyle="primary"
+            disabled={this.isBtnDisabled()}
+            onClick={this.gotoSlice.bind(this)}
+          >
+            {t('Create new slice')}
+          </Button>
+          <br /><br />
         </Panel>
       </div>
     );
diff --git a/superset/connectors/base/models.py b/superset/connectors/base/models.py
index 7a11598..68a020e 100644
--- a/superset/connectors/base/models.py
+++ b/superset/connectors/base/models.py
@@ -207,6 +207,10 @@ class BaseDatasource(AuditMixinNullable, ImportMixin):
         values in filters in the explore view"""
         raise NotImplementedError()
 
+    @staticmethod
+    def default_query(qry):
+        return qry
+
 
 class BaseColumn(AuditMixinNullable, ImportMixin):
     """Interface for column"""
diff --git a/superset/connectors/connector_registry.py b/superset/connectors/connector_registry.py
index 0a6291a..79f876a 100644
--- a/superset/connectors/connector_registry.py
+++ b/superset/connectors/connector_registry.py
@@ -33,8 +33,10 @@ class ConnectorRegistry(object):
     def get_all_datasources(cls, session):
         datasources = []
         for source_type in ConnectorRegistry.sources:
-            datasources.extend(
-                session.query(ConnectorRegistry.sources[source_type]).all())
+            source_class = ConnectorRegistry.sources[source_type]
+            qry = session.query(source_class)
+            qry = source_class.default_query(qry)
+            datasources.extend(qry.all())
         return datasources
 
     @classmethod
diff --git a/superset/connectors/sqla/models.py b/superset/connectors/sqla/models.py
index 7033048..8ed7080 100644
--- a/superset/connectors/sqla/models.py
+++ b/superset/connectors/sqla/models.py
@@ -268,6 +268,7 @@ class SqlaTable(Model, BaseDatasource):
         foreign_keys=[database_id])
     schema = Column(String(255))
     sql = Column(Text)
+    is_sqllab_view = Column(Boolean, default=False)
 
     baselink = 'tablemodelview'
 
@@ -819,6 +820,10 @@ class SqlaTable(Model, BaseDatasource):
             query = query.filter_by(schema=schema)
         return query.all()
 
+    @staticmethod
+    def default_query(qry):
+        return qry.filter_by(is_sqllab_view=False)
+
 
 sa.event.listen(SqlaTable, 'after_insert', set_perm)
 sa.event.listen(SqlaTable, 'after_update', set_perm)
diff --git a/superset/connectors/sqla/views.py b/superset/connectors/sqla/views.py
index 3d47795..2b8da0e 100644
--- a/superset/connectors/sqla/views.py
+++ b/superset/connectors/sqla/views.py
@@ -171,12 +171,15 @@ class TableModelView(DatasourceModelView, DeleteMixin, YamlExportMixin):
 # noqa
         'table_name', 'sql', 'filter_select_enabled', 'slices',
         'fetch_values_predicate', 'database', 'schema',
         'description', 'owner',
-        'main_dttm_col', 'default_endpoint', 'offset', 'cache_timeout']
+        'main_dttm_col', 'default_endpoint', 'offset', 'cache_timeout',
+        'is_sqllab_view',
+    ]
+    base_filters = [['id', DatasourceFilter, lambda: []]]
     show_columns = edit_columns + ['perm']
     related_views = [TableColumnInlineView, SqlMetricInlineView]
     base_order = ('changed_on', 'desc')
     search_columns = (
-        'database', 'schema', 'table_name', 'owner',
+        'database', 'schema', 'table_name', 'owner', 'is_sqllab_view',
     )
     description_columns = {
         'slices': _(
@@ -213,8 +216,10 @@ class TableModelView(DatasourceModelView, DeleteMixin, YamlExportMixin):
 # noqa
             "Whether to populate the filter's dropdown in the explore "
             "view's filter section with a list of distinct values fetched "
             'from the backend on the fly'),
+        'is_sqllab_view': _(
+            "Whether the table was generated by the 'Visualize' flow "
+            'in SQL Lab'),
     }
-    base_filters = [['id', DatasourceFilter, lambda: []]]
     label_columns = {
         'slices': _('Associated Charts'),
         'link': _('Table'),
@@ -231,6 +236,7 @@ class TableModelView(DatasourceModelView, DeleteMixin, YamlExportMixin):
 # noqa
         'owner': _('Owner'),
         'main_dttm_col': _('Main Datetime Column'),
         'description': _('Description'),
+        'is_sqllab_view': _('SQL Lab View'),
     }
 
     def pre_add(self, table):
@@ -298,13 +304,14 @@ class TableModelView(DatasourceModelView, DeleteMixin, YamlExportMixin):
 # noqa
         return redirect('/tablemodelview/list/')
 
 
-appbuilder.add_view(
-    TableModelView,
+appbuilder.add_view_no_menu(TableModelView)
+appbuilder.add_link(
     'Tables',
     label=__('Tables'),
+    href='/tablemodelview/list/?_flt_1_is_sqllab_view=y',
+    icon='fa-upload',
     category='Sources',
     category_label=__('Sources'),
-    icon='fa-table',
-)
+    category_icon='fa-table')
 
 appbuilder.add_separator('Sources')
diff --git a/superset/migrations/versions/130915240929_is_sqllab_viz_flow.py b/superset/migrations/versions/130915240929_is_sqllab_viz_flow.py
new file mode 100644
index 0000000..be17c50
--- /dev/null
+++ b/superset/migrations/versions/130915240929_is_sqllab_viz_flow.py
@@ -0,0 +1,54 @@
+"""is_sqllab_view
+
+Revision ID: 130915240929
+Revises: f231d82b9b26
+Create Date: 2018-04-03 08:19:34.098789
+
+"""
+from alembic import op
+import sqlalchemy as sa
+from sqlalchemy.ext.declarative import declarative_base
+
+from superset import db
+
+# revision identifiers, used by Alembic.
+revision = '130915240929'
+down_revision = 'f231d82b9b26'
+
+Base = declarative_base()
+
+
+class Table(Base):
+    """Declarative class to do query in upgrade"""
+    __tablename__ = 'tables'
+    id = sa.Column(sa.Integer, primary_key=True)
+    sql = sa.Column(sa.Text)
+    is_sqllab_view = sa.Column(sa.Boolean())
+
+
+def upgrade():
+    bind = op.get_bind()
+    op.add_column(
+        'tables',
+        sa.Column(
+            'is_sqllab_view',
+            sa.Boolean(),
+            nullable=True,
+            default=False,
+            server_default=sa.false(),
+        ),
+    )
+
+    session = db.Session(bind=bind)
+
+    # Use Slice class defined here instead of models.Slice
+    for tbl in session.query(Table).all():
+        if tbl.sql:
+            tbl.is_sqllab_view = True
+            session.merge(tbl)
+    session.commit()
+    db.session.close()
+
+
+def downgrade():
+    op.drop_column('tables', 'is_sqllab_view')
diff --git a/superset/views/core.py b/superset/views/core.py
index 6ffa4ee..6629dbd 100755
--- a/superset/views/core.py
+++ b/superset/views/core.py
@@ -2144,6 +2144,7 @@ class Superset(BaseSupersetView):
             table = SqlaTable(table_name=table_name)
         table.database_id = data.get('dbId')
         table.schema = data.get('schema')
+        table.is_sqllab_view = True
         q = SupersetQuery(data.get('sql'))
         table.sql = q.stripped()
         db.session.add(table)

-- 
To stop receiving notification emails like this one, please contact
maximebeauchemin@apache.org.

Mime
View raw message