diff --git a/rd_service/data/manager.py b/rd_service/data/manager.py index d4df6d13..52d2dd54 100644 --- a/rd_service/data/manager.py +++ b/rd_service/data/manager.py @@ -153,12 +153,12 @@ class Manager(object): def start_workers(self, workers_count, connection_string): if self.workers: return self.workers - - if settings.CONNECTION_ADAPTER == "mysql": - import query_runner_mysql + + if getattr(settings, 'CONNECTION_ADAPTER', None) == "mysql": + import query_runner_mysql runner = query_runner_mysql.mysql(connection_string) else: - import query_runner + import query_runner runner = query_runner.redshift(connection_string) redis_connection_params = self.redis_connection.connection_pool.connection_kwargs diff --git a/rd_service/data/models.py b/rd_service/data/models.py index b63da9fa..c56ef3ed 100644 --- a/rd_service/data/models.py +++ b/rd_service/data/models.py @@ -51,6 +51,12 @@ class Query(models.Model): app_label = 'redash' db_table = 'queries' + def create_default_visualizations(self): + table_visualization = Visualization(query=self, name="Table", + description=self.description, + type="TABLE", options="{}") + table_visualization.save() + def to_dict(self, with_result=True, with_stats=False, with_visualizations=False): d = { diff --git a/rd_service/migrate.py b/rd_service/migrate.py index caeff82f..2930b7b4 100644 --- a/rd_service/migrate.py +++ b/rd_service/migrate.py @@ -17,36 +17,51 @@ from data.models import * # ALTER TABLE widgets ADD COLUMN "visualization_id" integer REFERENCES "visualizations" ("id") DEFERRABLE INITIALLY DEFERRED; if __name__ == '__main__': - print 'migrating Widgets -> Visualizations ...' - default_options = {"series": {"type": "bar"}} + # create 'table' visualization for all queries + print 'creating TABLE visualizations ...' + for query in Query.objects.all(): + vis = Visualization(query=query, name="Table", + description=query.description, + type="TABLE", options="{}") + vis.save() + + + # create 'cohort' visualization for all queries named with 'cohort' + print 'creating COHORT visualizations ...' for query in Query.objects.filter(name__icontains="cohort"): - vis = Visualization(query=query, name=query.name, + vis = Visualization(query=query, name="Cohort", description=query.description, type="COHORT", options="{}") vis.save() + # create visualization for every widget (unless it already exists) + print 'migrating Widgets -> Visualizations ...' for widget in Widget.objects.all(): - print 'processing widget %d' % widget.id + print 'processing widget %d:' % widget.id, query = widget.query vis_type = widget.type.upper() vis = query.visualizations.filter(type=vis_type) if vis: - print 'found' + print 'visualization exists' widget.visualization = vis[0] widget.save() else: + vis_name = widget.type.title() + options = json.loads(widget.options) vis_options = {"series": options} if options else default_options vis_options = json.dumps(vis_options) - vis = Visualization(query=query, name=query.name, - description=query.description, - type=vis_type, options=vis_options) + vis = Visualization(query=query, name=vis_name, + description=query.description, + type=vis_type, options=vis_options) + + print 'created visualization %s' % vis_type vis.save() widget.visualization = vis widget.save() \ No newline at end of file diff --git a/rd_service/server.py b/rd_service/server.py index 5b09079e..edd234ce 100644 --- a/rd_service/server.py +++ b/rd_service/server.py @@ -215,6 +215,7 @@ class QueriesHandler(BaseAuthenticatedHandler): query_def['user'] = self.current_user query = data.models.Query(**query_def) query.save() + query.create_default_visualizations() self.write_json(query.to_dict(with_result=False)) diff --git a/rd_ui/app/scripts/directives.js b/rd_ui/app/scripts/directives.js index c01a6923..beb9e675 100644 --- a/rd_ui/app/scripts/directives.js +++ b/rd_ui/app/scripts/directives.js @@ -59,8 +59,7 @@ scope.advancedMode = false; scope.visTypes = { 'Chart': Visualization.prototype.TYPES.CHART, - 'Cohort': Visualization.prototype.TYPES.COHORT, - 'Table': Visualization.prototype.TYPES.GRID + 'Cohort': Visualization.prototype.TYPES.COHORT }; scope.seriesTypes = { 'Line': Visualization.prototype.SERIES_TYPES.LINE, @@ -77,7 +76,7 @@ scope.vis = { 'query_id': q.id, 'type': Visualization.prototype.TYPES.CHART, - 'name': q.name, + 'name': '', 'description': q.description, 'options': newOptions() }; @@ -99,6 +98,14 @@ }; } + scope.$watch('vis.type', function(type) { + // if not edited by user, set name to match type + if (type && scope.vis && !scope.visForm.name.$dirty) { + // poor man's titlecase + scope.vis.name = scope.vis.type[0] + scope.vis.type.slice(1).toLowerCase(); + } + }); + scope.toggleAdvancedMode = function() { scope.advancedMode = !scope.advancedMode; }; @@ -244,10 +251,6 @@ reset(); - $scope.toggleView = function(viewName) { - $scope.currentView = ($scope.currentView == viewName) ? '' : viewName; - }; - $scope.loadVisualizations = function() { if (!$scope.queryId) { return; diff --git a/rd_ui/app/scripts/query_fiddle/renderers.js b/rd_ui/app/scripts/query_fiddle/renderers.js index 9471e028..786442cb 100644 --- a/rd_ui/app/scripts/query_fiddle/renderers.js +++ b/rd_ui/app/scripts/query_fiddle/renderers.js @@ -9,7 +9,6 @@ renderers.directive('visualizationRenderer', function() { }, template: '