feat(sqllab): Add a configuration option to disable data preview (#19104)

This commit is contained in:
cccs-Dustin 2022-03-17 09:22:57 -04:00 committed by GitHub
parent cfb967f430
commit 02ef9ca4cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 175 additions and 42 deletions

View File

@ -2248,6 +2248,9 @@
"allows_virtual_table_explore": {
"type": "boolean"
},
"disable_data_preview": {
"type": "boolean"
},
"backend": {
"type": "string"
},
@ -2472,6 +2475,9 @@
"allows_virtual_table_explore": {
"readOnly": true
},
"disable_data_preview": {
"readOnly": true
},
"backend": {
"readOnly": true
},
@ -2571,7 +2577,7 @@
"type": "boolean"
},
"extra": {
"description": "<p>JSON string containing extra configuration elements.<br>1. The <code>engine_params</code> object gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/latest/core/engines.html#sqlalchemy.create_engine\">sqlalchemy.create_engine</a> call, while the <code>metadata_params</code> gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/rel_1_0/core/metadata.html#sqlalchemy.schema.MetaData\">sqlalchemy.MetaData</a> call.<br>2. The <code>metadata_cache_timeout</code> is a cache timeout setting in seconds for metadata fetch of this database. Specify it as <strong>\"metadata_cache_timeout\": {\"schema_cache_timeout\": 600, \"table_cache_timeout\": 600}</strong>. If unset, cache will not be enabled for the functionality. A timeout of 0 indicates that the cache never expires.<br>3. The <code>schemas_allowed_for_csv_upload</code> is a comma separated list of schemas that CSVs are allowed to upload to. Specify it as <strong>\"schemas_allowed_for_csv_upload\": [\"public\", \"csv_upload\"]</strong>. If database flavor does not support schema or any schema is allowed to be accessed, just leave the list empty<br>4. the <code>version</code> field is a string specifying the this db's version. This should be used with Presto DBs so that the syntax is correct<br>5. The <code>allows_virtual_table_explore</code> field is a boolean specifying whether or not the Explore button in SQL Lab results is shown.</p>",
"description": "<p>JSON string containing extra configuration elements.<br>1. The <code>engine_params</code> object gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/latest/core/engines.html#sqlalchemy.create_engine\">sqlalchemy.create_engine</a> call, while the <code>metadata_params</code> gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/rel_1_0/core/metadata.html#sqlalchemy.schema.MetaData\">sqlalchemy.MetaData</a> call.<br>2. The <code>metadata_cache_timeout</code> is a cache timeout setting in seconds for metadata fetch of this database. Specify it as <strong>\"metadata_cache_timeout\": {\"schema_cache_timeout\": 600, \"table_cache_timeout\": 600}</strong>. If unset, cache will not be enabled for the functionality. A timeout of 0 indicates that the cache never expires.<br>3. The <code>schemas_allowed_for_csv_upload</code> is a comma separated list of schemas that CSVs are allowed to upload to. Specify it as <strong>\"schemas_allowed_for_csv_upload\": [\"public\", \"csv_upload\"]</strong>. If database flavor does not support schema or any schema is allowed to be accessed, just leave the list empty<br>4. the <code>version</code> field is a string specifying the this db's version. This should be used with Presto DBs so that the syntax is correct<br>5. The <code>allows_virtual_table_explore</code> field is a boolean specifying whether or not the Explore button in SQL Lab results is shown<br>6. The <code>disable_data_preview</code> field is a boolean specifying whether or not data preview queries will be run when fetching table metadata in SQL Lab.</p>",
"type": "string"
},
"force_ctas_schema": {
@ -2663,7 +2669,7 @@
"type": "boolean"
},
"extra": {
"description": "<p>JSON string containing extra configuration elements.<br>1. The <code>engine_params</code> object gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/latest/core/engines.html#sqlalchemy.create_engine\">sqlalchemy.create_engine</a> call, while the <code>metadata_params</code> gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/rel_1_0/core/metadata.html#sqlalchemy.schema.MetaData\">sqlalchemy.MetaData</a> call.<br>2. The <code>metadata_cache_timeout</code> is a cache timeout setting in seconds for metadata fetch of this database. Specify it as <strong>\"metadata_cache_timeout\": {\"schema_cache_timeout\": 600, \"table_cache_timeout\": 600}</strong>. If unset, cache will not be enabled for the functionality. A timeout of 0 indicates that the cache never expires.<br>3. The <code>schemas_allowed_for_csv_upload</code> is a comma separated list of schemas that CSVs are allowed to upload to. Specify it as <strong>\"schemas_allowed_for_csv_upload\": [\"public\", \"csv_upload\"]</strong>. If database flavor does not support schema or any schema is allowed to be accessed, just leave the list empty<br>4. the <code>version</code> field is a string specifying the this db's version. This should be used with Presto DBs so that the syntax is correct<br>5. The <code>allows_virtual_table_explore</code> field is a boolean specifying whether or not the Explore button in SQL Lab results is shown.</p>",
"description": "<p>JSON string containing extra configuration elements.<br>1. The <code>engine_params</code> object gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/latest/core/engines.html#sqlalchemy.create_engine\">sqlalchemy.create_engine</a> call, while the <code>metadata_params</code> gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/rel_1_0/core/metadata.html#sqlalchemy.schema.MetaData\">sqlalchemy.MetaData</a> call.<br>2. The <code>metadata_cache_timeout</code> is a cache timeout setting in seconds for metadata fetch of this database. Specify it as <strong>\"metadata_cache_timeout\": {\"schema_cache_timeout\": 600, \"table_cache_timeout\": 600}</strong>. If unset, cache will not be enabled for the functionality. A timeout of 0 indicates that the cache never expires.<br>3. The <code>schemas_allowed_for_csv_upload</code> is a comma separated list of schemas that CSVs are allowed to upload to. Specify it as <strong>\"schemas_allowed_for_csv_upload\": [\"public\", \"csv_upload\"]</strong>. If database flavor does not support schema or any schema is allowed to be accessed, just leave the list empty<br>4. the <code>version</code> field is a string specifying the this db's version. This should be used with Presto DBs so that the syntax is correct<br>5. The <code>allows_virtual_table_explore</code> field is a boolean specifying whether or not the Explore button in SQL Lab results is shown<br>6. The <code>disable_data_preview</code> field is a boolean specifying whether or not data preview queries will be run when fetching table metadata in SQL Lab.</p>",
"type": "string"
},
"force_ctas_schema": {
@ -2720,7 +2726,7 @@
"type": "string"
},
"extra": {
"description": "<p>JSON string containing extra configuration elements.<br>1. The <code>engine_params</code> object gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/latest/core/engines.html#sqlalchemy.create_engine\">sqlalchemy.create_engine</a> call, while the <code>metadata_params</code> gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/rel_1_0/core/metadata.html#sqlalchemy.schema.MetaData\">sqlalchemy.MetaData</a> call.<br>2. The <code>metadata_cache_timeout</code> is a cache timeout setting in seconds for metadata fetch of this database. Specify it as <strong>\"metadata_cache_timeout\": {\"schema_cache_timeout\": 600, \"table_cache_timeout\": 600}</strong>. If unset, cache will not be enabled for the functionality. A timeout of 0 indicates that the cache never expires.<br>3. The <code>schemas_allowed_for_csv_upload</code> is a comma separated list of schemas that CSVs are allowed to upload to. Specify it as <strong>\"schemas_allowed_for_csv_upload\": [\"public\", \"csv_upload\"]</strong>. If database flavor does not support schema or any schema is allowed to be accessed, just leave the list empty<br>4. the <code>version</code> field is a string specifying the this db's version. This should be used with Presto DBs so that the syntax is correct<br>5. The <code>allows_virtual_table_explore</code> field is a boolean specifying whether or not the Explore button in SQL Lab results is shown.</p>",
"description": "<p>JSON string containing extra configuration elements.<br>1. The <code>engine_params</code> object gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/latest/core/engines.html#sqlalchemy.create_engine\">sqlalchemy.create_engine</a> call, while the <code>metadata_params</code> gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/rel_1_0/core/metadata.html#sqlalchemy.schema.MetaData\">sqlalchemy.MetaData</a> call.<br>2. The <code>metadata_cache_timeout</code> is a cache timeout setting in seconds for metadata fetch of this database. Specify it as <strong>\"metadata_cache_timeout\": {\"schema_cache_timeout\": 600, \"table_cache_timeout\": 600}</strong>. If unset, cache will not be enabled for the functionality. A timeout of 0 indicates that the cache never expires.<br>3. The <code>schemas_allowed_for_csv_upload</code> is a comma separated list of schemas that CSVs are allowed to upload to. Specify it as <strong>\"schemas_allowed_for_csv_upload\": [\"public\", \"csv_upload\"]</strong>. If database flavor does not support schema or any schema is allowed to be accessed, just leave the list empty<br>4. the <code>version</code> field is a string specifying the this db's version. This should be used with Presto DBs so that the syntax is correct<br>5. The <code>allows_virtual_table_explore</code> field is a boolean specifying whether or not the Explore button in SQL Lab results is shown<br>6. The <code>disable_data_preview</code> field is a boolean specifying whether or not data preview queries will be run when fetching table metadata in SQL Lab.</p>",
"type": "string"
},
"impersonate_user": {
@ -2768,7 +2774,7 @@
"type": "string"
},
"extra": {
"description": "<p>JSON string containing extra configuration elements.<br>1. The <code>engine_params</code> object gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/latest/core/engines.html#sqlalchemy.create_engine\">sqlalchemy.create_engine</a> call, while the <code>metadata_params</code> gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/rel_1_0/core/metadata.html#sqlalchemy.schema.MetaData\">sqlalchemy.MetaData</a> call.<br>2. The <code>metadata_cache_timeout</code> is a cache timeout setting in seconds for metadata fetch of this database. Specify it as <strong>\"metadata_cache_timeout\": {\"schema_cache_timeout\": 600, \"table_cache_timeout\": 600}</strong>. If unset, cache will not be enabled for the functionality. A timeout of 0 indicates that the cache never expires.<br>3. The <code>schemas_allowed_for_csv_upload</code> is a comma separated list of schemas that CSVs are allowed to upload to. Specify it as <strong>\"schemas_allowed_for_csv_upload\": [\"public\", \"csv_upload\"]</strong>. If database flavor does not support schema or any schema is allowed to be accessed, just leave the list empty<br>4. the <code>version</code> field is a string specifying the this db's version. This should be used with Presto DBs so that the syntax is correct<br>5. The <code>allows_virtual_table_explore</code> field is a boolean specifying whether or not the Explore button in SQL Lab results is shown.</p>",
"description": "<p>JSON string containing extra configuration elements.<br>1. The <code>engine_params</code> object gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/latest/core/engines.html#sqlalchemy.create_engine\">sqlalchemy.create_engine</a> call, while the <code>metadata_params</code> gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/rel_1_0/core/metadata.html#sqlalchemy.schema.MetaData\">sqlalchemy.MetaData</a> call.<br>2. The <code>metadata_cache_timeout</code> is a cache timeout setting in seconds for metadata fetch of this database. Specify it as <strong>\"metadata_cache_timeout\": {\"schema_cache_timeout\": 600, \"table_cache_timeout\": 600}</strong>. If unset, cache will not be enabled for the functionality. A timeout of 0 indicates that the cache never expires.<br>3. The <code>schemas_allowed_for_csv_upload</code> is a comma separated list of schemas that CSVs are allowed to upload to. Specify it as <strong>\"schemas_allowed_for_csv_upload\": [\"public\", \"csv_upload\"]</strong>. If database flavor does not support schema or any schema is allowed to be accessed, just leave the list empty<br>4. the <code>version</code> field is a string specifying the this db's version. This should be used with Presto DBs so that the syntax is correct<br>5. The <code>allows_virtual_table_explore</code> field is a boolean specifying whether or not the Explore button in SQL Lab results is shown<br>6. The <code>disable_data_preview</code> field is a boolean specifying whether or not data preview queries will be run when fetching table metadata in SQL Lab.</p>",
"type": "string"
},
"impersonate_user": {

View File

@ -1018,28 +1018,13 @@ function getTableMetadata(table, query, dispatch) {
),
})
.then(({ json }) => {
const dataPreviewQuery = {
id: shortid.generate(),
dbId: query.dbId,
sql: json.selectStar,
tableName: table.name,
sqlEditorId: null,
tab: '',
runAsync: false,
ctas: false,
isDataPreview: true,
};
const newTable = {
...table,
...json,
expanded: true,
isMetadataLoading: false,
dataPreviewQueryId: dataPreviewQuery.id,
};
Promise.all([
dispatch(mergeTable(newTable, dataPreviewQuery)), // Merge table to tables in state
dispatch(runQuery(dataPreviewQuery)), // Run query to get preview data for table
]);
dispatch(mergeTable(newTable)); // Merge table to tables in state
return newTable;
})
.catch(() =>
@ -1082,7 +1067,7 @@ function getTableExtendedMetadata(table, query, dispatch) {
);
}
export function addTable(query, tableName, schemaName) {
export function addTable(query, database, tableName, schemaName) {
return function (dispatch) {
const table = {
dbId: query.dbId,
@ -1110,6 +1095,32 @@ export function addTable(query, tableName, schemaName) {
})
: Promise.resolve({ json: { id: shortid.generate() } });
if (!database.disable_data_preview && database.id === query.dbId) {
const dataPreviewQuery = {
id: shortid.generate(),
dbId: query.dbId,
sql: newTable.selectStar,
tableName: table.name,
sqlEditorId: null,
tab: '',
runAsync: database.allow_run_async,
ctas: false,
isDataPreview: true,
};
Promise.all([
dispatch(
mergeTable(
{
...newTable,
dataPreviewQueryId: dataPreviewQuery.id,
},
dataPreviewQuery,
),
),
dispatch(runQuery(dataPreviewQuery)),
]);
}
return sync
.then(({ json: resultJson }) =>
dispatch(mergeTable({ ...table, id: resultJson.id })),

View File

@ -727,28 +727,18 @@ describe('async actions', () => {
it('updates the table schema state in the backend', () => {
expect.assertions(5);
const results = {
data: mockBigNumber,
query: { sqlEditorId: 'null' },
query_id: 'efgh',
};
fetchMock.post(runQueryEndpoint, JSON.stringify(results), {
overwriteRoutes: true,
});
const database = { disable_data_preview: true };
const tableName = 'table';
const schemaName = 'schema';
const store = mockStore({});
const expectedActionTypes = [
actions.MERGE_TABLE, // addTable
actions.MERGE_TABLE, // getTableMetadata
actions.START_QUERY, // runQuery (data preview)
actions.MERGE_TABLE, // getTableExtendedMetadata
actions.QUERY_SUCCESS, // querySuccess
actions.MERGE_TABLE, // addTable
];
return store
.dispatch(actions.addTable(query, tableName, schemaName))
.dispatch(actions.addTable(query, database, tableName, schemaName))
.then(() => {
expect(store.getActions().map(a => a.type)).toEqual(
expectedActionTypes,
@ -759,6 +749,47 @@ describe('async actions', () => {
1,
);
// tab state is not updated, since no query was run
expect(fetchMock.calls(updateTabStateEndpoint)).toHaveLength(0);
});
});
it('updates and runs data preview query when configured', () => {
expect.assertions(5);
const results = {
data: mockBigNumber,
query: { sqlEditorId: 'null', dbId: 1 },
query_id: 'efgh',
};
fetchMock.post(runQueryEndpoint, JSON.stringify(results), {
overwriteRoutes: true,
});
const database = { disable_data_preview: false, id: 1 };
const tableName = 'table';
const schemaName = 'schema';
const store = mockStore({});
const expectedActionTypes = [
actions.MERGE_TABLE, // addTable
actions.MERGE_TABLE, // getTableMetadata
actions.MERGE_TABLE, // getTableExtendedMetadata
actions.MERGE_TABLE, // addTable (data preview)
actions.START_QUERY, // runQuery (data preview)
actions.MERGE_TABLE, // addTable
actions.QUERY_SUCCESS, // querySuccess
];
return store
.dispatch(actions.addTable(query, database, tableName, schemaName))
.then(() => {
expect(store.getActions().map(a => a.type)).toEqual(
expectedActionTypes,
);
expect(fetchMock.calls(updateTableSchemaEndpoint)).toHaveLength(1);
expect(fetchMock.calls(getTableMetadataEndpoint)).toHaveLength(1);
expect(fetchMock.calls(getExtraTableMetadataEndpoint)).toHaveLength(
1,
);
// tab state is not updated, since the query is a data preview
expect(fetchMock.calls(updateTabStateEndpoint)).toHaveLength(0);
});

View File

@ -43,11 +43,17 @@ interface Props {
actions: {
queryEditorSetSelectedText: (edit: any, text: null | string) => void;
queryEditorSetFunctionNames: (queryEditor: object, dbId: number) => void;
addTable: (queryEditor: any, value: any, schema: any) => void;
addTable: (
queryEditor: any,
database: any,
value: any,
schema: any,
) => void;
};
autocomplete: boolean;
onBlur: (sql: string) => void;
sql: string;
database: any;
schemas: any[];
tables: any[];
functionNames: string[];
@ -210,6 +216,7 @@ class AceEditorWrapper extends React.PureComponent<Props, State> {
if (data.meta === 'table') {
this.props.actions.addTable(
this.props.queryEditor,
this.props.database,
data.value,
this.props.queryEditor.schema,
);

View File

@ -514,6 +514,7 @@ class SqlEditor extends React.PureComponent {
onChange={this.onSqlChanged}
queryEditor={this.props.queryEditor}
sql={this.props.queryEditor.sql}
database={this.props.database}
schemas={this.props.queryEditor.schemaOptions}
tables={this.props.queryEditor.tableOptions}
functionNames={this.props.queryEditor.functionNames}

View File

@ -36,7 +36,7 @@ interface actionsTypes {
queryEditorSetFunctionNames: (queryEditor: QueryEditor, dbId: number) => void;
collapseTable: (table: Table) => void;
expandTable: (table: Table) => void;
addTable: (queryEditor: any, value: any, schema: any) => void;
addTable: (queryEditor: any, database: any, value: any, schema: any) => void;
setDatabases: (arg0: any) => {};
addDangerToast: (msg: string) => void;
queryEditorSetSchema: (queryEditor: QueryEditor, schema?: string) => void;
@ -103,7 +103,7 @@ export default function SqlEditorLeftBar({
const onTableChange = (tableName: string, schemaName: string) => {
if (tableName && schemaName) {
actions.addTable(queryEditor, tableName, schemaName);
actions.addTable(queryEditor, database, tableName, schemaName);
}
};

View File

@ -76,6 +76,7 @@ beforeEach(() => {
allows_cost_estimate: 'Allows Cost Estimate',
allows_subquery: 'Allows Subquery',
allows_virtual_table_explore: 'Allows Virtual Table Explore',
disable_data_preview: 'Disables SQL Lab Data Preview',
backend: 'Backend',
changed_on: 'Changed On',
changed_on_delta_humanized: 'Changed On Delta Humanized',
@ -97,6 +98,7 @@ beforeEach(() => {
'allows_cost_estimate',
'allows_subquery',
'allows_virtual_table_explore',
'disable_data_preview',
'backend',
'changed_on',
'changed_on_delta_humanized',
@ -130,6 +132,7 @@ beforeEach(() => {
allows_cost_estimate: null,
allows_subquery: true,
allows_virtual_table_explore: true,
disable_data_preview: false,
backend: 'postgresql',
changed_on: '2021-03-09T19:02:07.141095',
changed_on_delta_humanized: 'a day ago',
@ -150,6 +153,7 @@ beforeEach(() => {
allows_cost_estimate: null,
allows_subquery: true,
allows_virtual_table_explore: true,
disable_data_preview: false,
backend: 'mysql',
changed_on: '2021-03-09T19:02:07.141095',
changed_on_delta_humanized: 'a day ago',

View File

@ -182,7 +182,7 @@ const ExtraOptions = ({
/>
</div>
</StyledInputContainer>
<StyledInputContainer>
<StyledInputContainer css={no_margin_bottom}>
<div className="input-container">
<IndeterminateCheckbox
id="allows_virtual_table_explore"
@ -198,6 +198,24 @@ const ExtraOptions = ({
/>
</div>
</StyledInputContainer>
<StyledInputContainer>
<div className="input-container">
<IndeterminateCheckbox
id="disable_data_preview"
indeterminate={false}
checked={!!db?.extra_json?.disable_data_preview}
onChange={onExtraInputChange}
labelText={t('Disable SQL Lab data preview queries')}
/>
<InfoTooltip
tooltip={t(
'Disable data preview when fetching table metadata in SQL Lab. ' +
' Useful to avoid browser performance issues when using ' +
' databases with very wide tables.',
)}
/>
</div>
</StyledInputContainer>
</StyledExpandableForm>
</StyledInputContainer>
</Collapse.Panel>

View File

@ -591,6 +591,15 @@ describe('DatabaseModal', () => {
const allowDbExplorationText = screen.getByText(
/allow this database to be explored/i,
);
const disableSQLLabDataPreviewQueriesCheckbox = screen.getByRole(
'checkbox',
{
name: /Disable SQL Lab data preview queries/i,
},
);
const disableSQLLabDataPreviewQueriesText = screen.getByText(
/Disable SQL Lab data preview queries/i,
);
// ---------- Assertions ----------
const visibleComponents = [
@ -610,6 +619,7 @@ describe('DatabaseModal', () => {
checkboxOffSVGs[4],
checkboxOffSVGs[5],
checkboxOffSVGs[6],
checkboxOffSVGs[7],
tooltipIcons[0],
tooltipIcons[1],
tooltipIcons[2],
@ -617,6 +627,7 @@ describe('DatabaseModal', () => {
tooltipIcons[4],
tooltipIcons[5],
tooltipIcons[6],
tooltipIcons[7],
exposeInSQLLabText,
allowCTASText,
allowCVASText,
@ -627,6 +638,7 @@ describe('DatabaseModal', () => {
allowMultiSchemaMDFetchText,
enableQueryCostEstimationText,
allowDbExplorationText,
disableSQLLabDataPreviewQueriesText,
];
// These components exist in the DOM but are not visible
const invisibleComponents = [
@ -637,6 +649,7 @@ describe('DatabaseModal', () => {
allowMultiSchemaMDFetchCheckbox,
enableQueryCostEstimationCheckbox,
allowDbExplorationCheckbox,
disableSQLLabDataPreviewQueriesCheckbox,
];
visibleComponents.forEach(component => {
@ -645,8 +658,8 @@ describe('DatabaseModal', () => {
invisibleComponents.forEach(component => {
expect(component).not.toBeVisible();
});
expect(checkboxOffSVGs).toHaveLength(7);
expect(tooltipIcons).toHaveLength(7);
expect(checkboxOffSVGs).toHaveLength(8);
expect(tooltipIcons).toHaveLength(8);
});
it('renders the "Advanced" - PERFORMANCE tab correctly', async () => {

View File

@ -92,6 +92,7 @@ export type DatabaseObject = {
version?: string;
cost_estimate_enabled?: boolean; // in SQL Lab
disable_data_preview?: boolean; // in SQL Lab
};
// Temporary storage

View File

@ -175,6 +175,7 @@ class DatabaseSchema(Schema):
allows_subquery = fields.Bool()
allows_cost_estimate = fields.Bool()
allows_virtual_table_explore = fields.Bool()
disable_data_preview = fields.Bool()
explore_database_id = fields.Int()

View File

@ -145,6 +145,7 @@ class DatabaseRestApi(BaseSupersetModelRestApi):
"extra",
"force_ctas_schema",
"id",
"disable_data_preview",
]
add_columns = [
"database_name",

View File

@ -115,10 +115,12 @@ extra_description = markdown(
'["public", "csv_upload"]**. '
"If database flavor does not support schema or any schema is allowed "
"to be accessed, just leave the list empty<br/>"
"4. the ``version`` field is a string specifying the this db's version. "
"4. The ``version`` field is a string specifying the this db's version. "
"This should be used with Presto DBs so that the syntax is correct<br/>"
"5. The ``allows_virtual_table_explore`` field is a boolean specifying "
"whether or not the Explore button in SQL Lab results is shown.",
"whether or not the Explore button in SQL Lab results is shown.<br/>"
"6. The ``disable_data_preview`` field is a boolean specifying whether or not data "
"preview queries will be run when fetching table metadata in SQL Lab.",
True,
)
get_export_ids_schema = {"type": "array", "items": {"type": "integer"}}

View File

@ -212,6 +212,13 @@ class Database(
def explore_database_id(self) -> int:
return self.get_extra().get("explore_database_id", self.id)
@property
def disable_data_preview(self) -> bool:
# this will prevent any 'trash value' strings from going through
if self.get_extra().get("disable_data_preview", False) is not True:
return False
return True
@property
def data(self) -> Dict[str, Any]:
return {
@ -225,6 +232,7 @@ class Database(
"allows_virtual_table_explore": self.allows_virtual_table_explore,
"explore_database_id": self.explore_database_id,
"parameters": self.parameters,
"disable_data_preview": self.disable_data_preview,
"parameters_schema": self.parameters_schema,
}

View File

@ -182,6 +182,7 @@ DATABASE_KEYS = [
"expose_in_sqllab",
"force_ctas_schema",
"id",
"disable_data_preview",
]
DATASOURCE_MISSING_ERR = __("The data source seems to have been deleted")

View File

@ -145,7 +145,10 @@ class DatabaseMixin:
"4. the ``version`` field is a string specifying the this db's version. "
"This should be used with Presto DBs so that the syntax is correct<br/>"
"5. The ``allows_virtual_table_explore`` field is a boolean specifying "
"whether or not the Explore button in SQL Lab results is shown.",
"whether or not the Explore button in SQL Lab results is shown<br/>"
"6. The ``disable_data_preview`` field is a boolean specifying whether or"
"not data preview queries will be run when fetching table metadata in"
"SQL Lab.",
True,
),
"encrypted_extra": utils.markdown(

View File

@ -1517,6 +1517,29 @@ class TestCore(SupersetTestCase):
database.extra = json.dumps(extra)
self.assertEqual(database.allows_virtual_table_explore, True)
def test_data_preview_visibility(self):
# test that default visibility is allowed
database = utils.get_example_database()
self.assertEqual(database.disable_data_preview, False)
# test that visibility is disabled when extra is set to true
extra = database.get_extra()
extra["disable_data_preview"] = True
database.extra = json.dumps(extra)
self.assertEqual(database.disable_data_preview, True)
# test that visibility is enabled when extra is set to false
extra = database.get_extra()
extra["disable_data_preview"] = False
database.extra = json.dumps(extra)
self.assertEqual(database.disable_data_preview, False)
# test that visibility is not broken with bad values
extra = database.get_extra()
extra["disable_data_preview"] = "trash value"
database.extra = json.dumps(extra)
self.assertEqual(database.disable_data_preview, False)
def test_explore_database_id(self):
database = superset.utils.database.get_example_database()
explore_database = superset.utils.database.get_example_database()

View File

@ -179,12 +179,14 @@ class TestDatabaseApi(SupersetTestCase):
"changed_on_delta_humanized",
"created_by",
"database_name",
"disable_data_preview",
"explore_database_id",
"expose_in_sqllab",
"extra",
"force_ctas_schema",
"id",
]
self.assertGreater(response["count"], 0)
self.assertEqual(list(response["result"][0].keys()), expected_columns)