diff --git a/redash/models/__init__.py b/redash/models/__init__.py index ce3446c916..17b7842da6 100644 --- a/redash/models/__init__.py +++ b/redash/models/__init__.py @@ -216,7 +216,7 @@ def get_schema(self, refresh=False): schema = query_runner.get_schema(get_stats=refresh) try: - out_schema = self._sort_schema(schema) + out_schema = self._sort_schema(schema, settings.SCHEMAS_SORT_COLUMNS) except Exception: logging.exception("Error sorting schema columns for data_source {}".format(self.id)) out_schema = schema @@ -226,11 +226,17 @@ def get_schema(self, refresh=False): return out_schema - def _sort_schema(self, schema): - return [ - {"name": i["name"], "columns": sorted(i["columns"], key=lambda x: x["name"] if isinstance(x, dict) else x)} - for i in sorted(schema, key=lambda x: x["name"]) - ] + def _sort_schema(self, schema, sort_columns=True): + if sort_columns: + return [ + { + "name": i["name"], + "columns": sorted(i["columns"], key=lambda x: x["name"] if isinstance(x, dict) else x), + } + for i in sorted(schema, key=lambda x: x["name"]) + ] + else: + return sorted(schema, key=lambda x: x["name"]) @property def _schema_key(self): diff --git a/redash/settings/__init__.py b/redash/settings/__init__.py index 75c438cff2..3e4399add5 100644 --- a/redash/settings/__init__.py +++ b/redash/settings/__init__.py @@ -49,6 +49,7 @@ # default set query results expired ttl 86400 seconds QUERY_RESULTS_EXPIRED_TTL = int(os.environ.get("REDASH_QUERY_RESULTS_EXPIRED_TTL", "86400")) +SCHEMAS_SORT_COLUMNS = parse_boolean(os.environ.get("REDASH_SCHEMAS_SORT_COLUMNS", "true")) SCHEMAS_REFRESH_SCHEDULE = int(os.environ.get("REDASH_SCHEMAS_REFRESH_SCHEDULE", 30)) AUTH_TYPE = os.environ.get("REDASH_AUTH_TYPE", "api_key") diff --git a/tests/models/test_data_sources.py b/tests/models/test_data_sources.py index 7db4d463a3..7be96870dd 100644 --- a/tests/models/test_data_sources.py +++ b/tests/models/test_data_sources.py @@ -58,7 +58,28 @@ def test_schema_sorter(self): {"name": "zoo", "columns": ["is_cow", "is_snake", "is_zebra"]}, ] - real_output = self.factory.data_source._sort_schema(input_data) + real_output = self.factory.data_source._sort_schema(input_data, sort_columns=True) + + self.assertEqual(real_output, expected_output) + + def test_schema_sorter_columns_unsorted(self): + input_data = [ + {"name": "zoo", "columns": ["is_zebra", "is_snake", "is_cow"]}, + { + "name": "all_terain_vehicle", + "columns": ["has_wheels", "has_engine", "has_all_wheel_drive"], + }, + ] + + expected_output = [ + { + "name": "all_terain_vehicle", + "columns": ["has_wheels", "has_engine", "has_all_wheel_drive"], + }, + {"name": "zoo", "columns": ["is_zebra", "is_snake", "is_cow"]}, + ] + + real_output = self.factory.data_source._sort_schema(input_data, sort_columns=False) self.assertEqual(real_output, expected_output)