mirror of
https://github.com/apache/superset.git
synced 2024-09-17 11:09:47 -04:00
[sql lab] option to disable cross schema search (#4551)
* [sql lab] disable cross schema search This is killing our metastore as people type it emits large all-table-dump as they hit the keystroke. It never returns as it times out and hammers the poor metastore. Also some improvements around the disabling the table select on the left panel and having the table name not be sticky. * typo
This commit is contained in:
parent
34a081b926
commit
d522292b01
@ -241,6 +241,7 @@ class SqlEditor extends React.PureComponent {
|
|||||||
>
|
>
|
||||||
<SqlEditorLeftBar
|
<SqlEditorLeftBar
|
||||||
height={height}
|
height={height}
|
||||||
|
database={this.props.database}
|
||||||
queryEditor={this.props.queryEditor}
|
queryEditor={this.props.queryEditor}
|
||||||
tables={this.props.tables}
|
tables={this.props.tables}
|
||||||
actions={this.props.actions}
|
actions={this.props.actions}
|
||||||
|
@ -16,6 +16,7 @@ const propTypes = {
|
|||||||
height: PropTypes.number.isRequired,
|
height: PropTypes.number.isRequired,
|
||||||
tables: PropTypes.array,
|
tables: PropTypes.array,
|
||||||
actions: PropTypes.object,
|
actions: PropTypes.object,
|
||||||
|
database: PropTypes.object,
|
||||||
};
|
};
|
||||||
|
|
||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
@ -139,6 +140,14 @@ class SqlEditorLeftBar extends React.PureComponent {
|
|||||||
render() {
|
render() {
|
||||||
const shouldShowReset = window.location.search === '?reset=1';
|
const shouldShowReset = window.location.search === '?reset=1';
|
||||||
const tableMetaDataHeight = this.props.height - 130; // 130 is the height of the selects above
|
const tableMetaDataHeight = this.props.height - 130; // 130 is the height of the selects above
|
||||||
|
let tableSelectPlaceholder;
|
||||||
|
let tableSelectDisabled = false;
|
||||||
|
if (this.props.database && this.props.database.allow_multi_schema_metadata_fetch) {
|
||||||
|
tableSelectPlaceholder = t('Type to search ...');
|
||||||
|
} else {
|
||||||
|
tableSelectPlaceholder = t('Select table ');
|
||||||
|
tableSelectDisabled = true;
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<div className="clearfix sql-toolbar">
|
<div className="clearfix sql-toolbar">
|
||||||
<div>
|
<div>
|
||||||
@ -186,7 +195,6 @@ class SqlEditorLeftBar extends React.PureComponent {
|
|||||||
name="select-table"
|
name="select-table"
|
||||||
ref="selectTable"
|
ref="selectTable"
|
||||||
isLoading={this.state.tableLoading}
|
isLoading={this.state.tableLoading}
|
||||||
value={this.state.tableName}
|
|
||||||
placeholder={t('Add a table (%s)', this.state.tableOptions.length)}
|
placeholder={t('Add a table (%s)', this.state.tableOptions.length)}
|
||||||
autosize={false}
|
autosize={false}
|
||||||
onChange={this.changeTable.bind(this)}
|
onChange={this.changeTable.bind(this)}
|
||||||
@ -199,8 +207,8 @@ class SqlEditorLeftBar extends React.PureComponent {
|
|||||||
async
|
async
|
||||||
name="async-select-table"
|
name="async-select-table"
|
||||||
ref="selectTable"
|
ref="selectTable"
|
||||||
value={this.state.tableName}
|
placeholder={tableSelectPlaceholder}
|
||||||
placeholder={t('Type to search ...')}
|
disabled={tableSelectDisabled}
|
||||||
autosize={false}
|
autosize={false}
|
||||||
onChange={this.changeTable.bind(this)}
|
onChange={this.changeTable.bind(this)}
|
||||||
loadOptions={this.getTableNamesBySubStr.bind(this)}
|
loadOptions={this.getTableNamesBySubStr.bind(this)}
|
||||||
|
@ -23,6 +23,7 @@ describe('SqlEditorLeftBar', () => {
|
|||||||
},
|
},
|
||||||
tables: [table],
|
tables: [table],
|
||||||
queryEditor: defaultQueryEditor,
|
queryEditor: defaultQueryEditor,
|
||||||
|
database: {},
|
||||||
height: 0,
|
height: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -51,6 +51,7 @@ describe('TabbedSqlEditors', () => {
|
|||||||
tabHistory: initialState.tabHistory,
|
tabHistory: initialState.tabHistory,
|
||||||
editorHeight: '',
|
editorHeight: '',
|
||||||
getHeight: () => ('100px'),
|
getHeight: () => ('100px'),
|
||||||
|
database: {},
|
||||||
};
|
};
|
||||||
const getWrapper = () => (
|
const getWrapper = () => (
|
||||||
shallow(<TabbedSqlEditors {...mockedProps} />, {
|
shallow(<TabbedSqlEditors {...mockedProps} />, {
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
"""allow_multi_schema_metadata_fetch
|
||||||
|
|
||||||
|
Revision ID: e68c4473c581
|
||||||
|
Revises: e866bd2d4976
|
||||||
|
Create Date: 2018-03-06 12:24:30.896293
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = 'e68c4473c581'
|
||||||
|
down_revision = 'e866bd2d4976'
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
|
||||||
|
op.add_column(
|
||||||
|
'dbs',
|
||||||
|
sa.Column(
|
||||||
|
'allow_multi_schema_metadata_fetch',
|
||||||
|
sa.Boolean(),
|
||||||
|
nullable=True,
|
||||||
|
default=True,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
op.drop_column('dbs', 'allow_multi_schema_metadata_fetch')
|
@ -567,6 +567,7 @@ class Database(Model, AuditMixinNullable, ImportMixin):
|
|||||||
allow_ctas = Column(Boolean, default=False)
|
allow_ctas = Column(Boolean, default=False)
|
||||||
allow_dml = Column(Boolean, default=False)
|
allow_dml = Column(Boolean, default=False)
|
||||||
force_ctas_schema = Column(String(250))
|
force_ctas_schema = Column(String(250))
|
||||||
|
allow_multi_schema_metadata_fetch = Column(Boolean, default=True)
|
||||||
extra = Column(Text, default=textwrap.dedent("""\
|
extra = Column(Text, default=textwrap.dedent("""\
|
||||||
{
|
{
|
||||||
"metadata_params": {},
|
"metadata_params": {},
|
||||||
@ -593,6 +594,8 @@ class Database(Model, AuditMixinNullable, ImportMixin):
|
|||||||
return {
|
return {
|
||||||
'name': self.database_name,
|
'name': self.database_name,
|
||||||
'backend': self.backend,
|
'backend': self.backend,
|
||||||
|
'allow_multi_schema_metadata_fetch':
|
||||||
|
self.allow_multi_schema_metadata_fetch,
|
||||||
}
|
}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -736,6 +739,8 @@ class Database(Model, AuditMixinNullable, ImportMixin):
|
|||||||
|
|
||||||
def all_table_names(self, schema=None, force=False):
|
def all_table_names(self, schema=None, force=False):
|
||||||
if not schema:
|
if not schema:
|
||||||
|
if not self.allow_multi_schema_metadata_fetch:
|
||||||
|
return []
|
||||||
tables_dict = self.db_engine_spec.fetch_result_sets(
|
tables_dict = self.db_engine_spec.fetch_result_sets(
|
||||||
self, 'table', force=force)
|
self, 'table', force=force)
|
||||||
return tables_dict.get('', [])
|
return tables_dict.get('', [])
|
||||||
@ -744,6 +749,8 @@ class Database(Model, AuditMixinNullable, ImportMixin):
|
|||||||
|
|
||||||
def all_view_names(self, schema=None, force=False):
|
def all_view_names(self, schema=None, force=False):
|
||||||
if not schema:
|
if not schema:
|
||||||
|
if not self.allow_multi_schema_metadata_fetch:
|
||||||
|
return []
|
||||||
views_dict = self.db_engine_spec.fetch_result_sets(
|
views_dict = self.db_engine_spec.fetch_result_sets(
|
||||||
self, 'view', force=force)
|
self, 'view', force=force)
|
||||||
return views_dict.get('', [])
|
return views_dict.get('', [])
|
||||||
|
@ -199,7 +199,9 @@ class DatabaseView(SupersetModelView, DeleteMixin, YamlExportMixin): # noqa
|
|||||||
add_columns = [
|
add_columns = [
|
||||||
'database_name', 'sqlalchemy_uri', 'cache_timeout', 'extra',
|
'database_name', 'sqlalchemy_uri', 'cache_timeout', 'extra',
|
||||||
'expose_in_sqllab', 'allow_run_sync', 'allow_run_async',
|
'expose_in_sqllab', 'allow_run_sync', 'allow_run_async',
|
||||||
'allow_ctas', 'allow_dml', 'force_ctas_schema', 'impersonate_user']
|
'allow_ctas', 'allow_dml', 'force_ctas_schema', 'impersonate_user',
|
||||||
|
'allow_multi_schema_metadata_fetch',
|
||||||
|
]
|
||||||
search_exclude_columns = (
|
search_exclude_columns = (
|
||||||
'password', 'tables', 'created_by', 'changed_by', 'queries',
|
'password', 'tables', 'created_by', 'changed_by', 'queries',
|
||||||
'saved_queries')
|
'saved_queries')
|
||||||
@ -258,6 +260,10 @@ class DatabaseView(SupersetModelView, DeleteMixin, YamlExportMixin): # noqa
|
|||||||
'If Hive and hive.server2.enable.doAs is enabled, will run the queries as '
|
'If Hive and hive.server2.enable.doAs is enabled, will run the queries as '
|
||||||
'service account, but impersonate the currently logged on user '
|
'service account, but impersonate the currently logged on user '
|
||||||
'via hive.server2.proxy.user property.'),
|
'via hive.server2.proxy.user property.'),
|
||||||
|
'allow_multi_schema_metadata_fetch': _(
|
||||||
|
'Allow SQL Lab to fetch a list of all tables and all views across '
|
||||||
|
'all database schemas. For large data warehouse with thousands of '
|
||||||
|
'tables, this can be expensive and put strain on the system.'),
|
||||||
}
|
}
|
||||||
label_columns = {
|
label_columns = {
|
||||||
'expose_in_sqllab': _('Expose in SQL Lab'),
|
'expose_in_sqllab': _('Expose in SQL Lab'),
|
||||||
@ -314,6 +320,7 @@ class DatabaseAsync(DatabaseView):
|
|||||||
'id', 'database_name',
|
'id', 'database_name',
|
||||||
'expose_in_sqllab', 'allow_ctas', 'force_ctas_schema',
|
'expose_in_sqllab', 'allow_ctas', 'force_ctas_schema',
|
||||||
'allow_run_async', 'allow_run_sync', 'allow_dml',
|
'allow_run_async', 'allow_run_sync', 'allow_dml',
|
||||||
|
'allow_multi_schema_metadata_fetch',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user