Explorar o código

[impala] Update field list dynamically when creating a new dashboard

Romain Rigaux %!s(int64=11) %!d(string=hai) anos
pai
achega
9af37d4

+ 14 - 6
apps/impala/src/impala/models.py

@@ -39,12 +39,8 @@ class Dashboard():
 
   def get_json(self, user):
     _data = self.get_data()
-    
-    query_server = get_query_server_config(name='impala')
-    db = dbms.get(user, query_server=query_server)
-    
-    _table = db.get_table(_data['properties'][0]['database'], _data['properties'][0]['table'])
-    _data['properties'][0]['fields'] = [dict([('name', col.name), ('type', col.type), ('comment', col.comment)]) for col in _table.cols]
+
+    _data['properties'][0]['fields'] = Controller(user).get_fields(_data['properties'][0]['database'], _data['properties'][0]['table'])
     
     return json.dumps(_data)
  
@@ -52,4 +48,16 @@ class Dashboard():
     return json.loads(self.data)
 
     
+class Controller():
+  
+  def __init__(self, user):
+    query_server = get_query_server_config(name='impala')
+    self.db = dbms.get(user, query_server=query_server)      
+      
+  def get_fields(self, database, table):
+        
+    _table = self.db.get_table(database, table)
+    return [dict([('name', col.name), ('type', col.type), ('comment', col.comment)]) for col in _table.cols]    
+        
+        
         

+ 3 - 5
apps/impala/src/impala/templates/dashboard.mako

@@ -280,7 +280,7 @@ ${ dashboard.import_charts() }
 
 
 <script type="text/javascript">
-  var viewModel = new ImpalaDashboardViewModel(${ query_json | n,unicode }, ${ dashboard_json | n,unicode  });
+  var viewModel = new ImpalaDashboardViewModel(${ query_json | n,unicode }, ${ dashboard_json | n,unicode  },  ${ initial_json | n,unicode  });
   ko.applyBindings(viewModel);
 
   var HIVE_AUTOCOMPLETE_BASE_URL = "/impala/api/autocomplete/";
@@ -308,9 +308,9 @@ ${ dashboard.import_charts() }
         $(".chosen-select").trigger("chosen:updated");
       }, 200)
     });
+    
     hac_getDatabases(function (dbs) {
       viewModel.dashboard.updateDropdownDatabases(dbs);
-
       if (typeof callback != "undefined"){
         callback(dbs);
       }
@@ -326,9 +326,7 @@ ${ dashboard.import_charts() }
           disable_search_threshold: 5,
           width: "130px",
           no_results_text: "${_('Oops, no table found!')}"
-          }).change(function () {
-            viewModel.dashboard.properties([{'database': viewModel.dashboard.selectedDropdownDb(), 'table': viewModel.dashboard.selectedDropdownTable()}]);
-          });
+        });
         $(".chosen-select").trigger("chosen:updated");
       }, 200);
       if (typeof callback != "undefined"){

+ 1 - 0
apps/impala/src/impala/urls.py

@@ -26,6 +26,7 @@ urlpatterns = patterns('impala.views',
   
   url(r'^dashboard/new_facet$', 'new_facet', name='new_facet'),
   url(r'^dashboard/new_search$', 'new_search', name='new_search'),
+  url(r'^dashboard/get_fields', 'get_fields', name='get_fields'),
 )
 
 urlpatterns += beeswax_urls

+ 34 - 13
apps/impala/src/impala/views.py

@@ -28,7 +28,8 @@ from desktop.lib.django_util import render
 from beeswax.design import hql_query
 from beeswax.server import dbms
 from beeswax.server.dbms import get_query_server_config
-from impala.models import Dashboard
+
+from impala.models import Dashboard, Controller
 
 
 LOG = logging.getLogger(__name__)
@@ -40,6 +41,7 @@ def dashboard(request):
   return render('dashboard.mako', request, {
     'query_json': json.dumps({}),
     'dashboard_json': dashboard.get_json(request.user), 
+    'initial_json': ''
   })
 
 
@@ -75,8 +77,8 @@ def query(request):
     fields = [fq['field'] for fq in fqs]
     result['selected'] = facet['field'] in fields
   else:
-    fields = ', '.join(dashboard['resultsetSelectedFields'])
-    hql = "SELECT %(fields)s FROM %(database)s.%(table)s" % {
+    fields = ', '.join(dashboard['resultsetSelectedFields']) if dashboard['resultsetSelectedFields'] else '*'
+    hql = "SELECT %(fields)s FROM %(database)s.%(table)s LIMIT 100" % {
         'database': database, 
         'table': table,
         'fields': fields
@@ -127,19 +129,38 @@ def new_search(request):
 
   return render('dashboard.mako', request, {
     'query_json': json.dumps({}),
-    'dashboard_json': json.dumps({'layout': [
-              {"size":2,"rows":[],"drops":["temp"],"klass":"card card-home card-column span2"},
-              {"size":10,"rows":[{"widgets":[
-                  {"size":12,"name":"Grid Results","id":"52f07188-f30f-1296-2450-f77e02e1a5c0","widgetType":"resultset-widget",
-                   "properties":{},"offset":0,"isLoading":True,"klass":"card card-widget span12"}]}],
-              "drops":["temp"],"klass":"card card-home card-column span10"}
-         ],
-        'facets': [],
-        'properties': [{'database': 'default', 'table': 'sample_07'}]
-        }),
+    'dashboard_json': json.dumps({
+      'layout': [],
+      'facets': [],
+      'properties': [{'database': '', 'table': '', 'fields': []}]
+      }),
+     'initial_json': json.dumps({
+        'layout': [
+           {"size":2,"rows":[{"widgets":[]}],"drops":["temp"],"klass":"card card-home card-column span2"},
+           {"size":10,"rows":[{"widgets":[
+               {"size":12,"name":"Grid Results","id":"52f07188-f30f-1296-2450-f77e02e1a5c0","widgetType":"resultset-widget",
+                "properties":{},"offset":0,"isLoading":True,"klass":"card card-widget span12"}]}],
+               "drops":["temp"],"klass":"card card-home card-column span10"}
+         ]
+     })
   })
 
 
+def get_fields(request):
+  result = {'status': -1, 'message': 'Error'}
+
+  try:
+    database = request.POST.get('database')
+    table = request.POST.get('table')
+
+    result['message'] = ''
+    result['fields'] = Controller(request.user).get_fields(database, table)
+    result['status'] = 0
+  except Exception, e:
+    result['message'] = unicode(str(e), "utf8")
+
+  return HttpResponse(json.dumps(result), mimetype="application/json") 
+
 
 def _create_facet(collection, user, facet_id, facet_label, facet_field, widget_type):
   properties = {

+ 34 - 5
apps/impala/static/js/impala-dashboard.ko.js

@@ -103,9 +103,22 @@ var Dashboard = function (vm, dashboard) {
 
   self.dropdownDbs = ko.observableArray([]);
   self.selectedDropdownDb = ko.observable("");
+  self.selectedDropdownDb.subscribe(function(value) {
+	self.properties()[0].database(self.selectedDropdownDb());
+	if (self.selectedDropdownDb() && self.selectedDropdownTable()) {
+	  self.updateFields(); 
+	}
+  });  
+
   self.dropdownTables = ko.observableArray([]);
   self.selectedDropdownTable = ko.observable("");
-
+  self.selectedDropdownTable.subscribe(function(value) {
+	self.properties()[0].table(self.selectedDropdownTable());
+	if (self.selectedDropdownDb() && self.selectedDropdownTable()) {
+	  self.updateFields(); 
+	}
+  });
+  
   self.updateDropdownDatabases = function(databases) {
     if (databases) {
       var i = databases.indexOf("_impala_builtins"); // Blacklist of system databases
@@ -118,12 +131,12 @@ var Dashboard = function (vm, dashboard) {
 
   self.fields = ko.computed(function () {
     if (self.properties() != null && self.properties().length > 0 && self.properties()[0].fields != null){
-	    return self.properties()[0].fields();
+	  return self.properties()[0].fields();
     }
     return [];
   });
   self.fieldNames = ko.computed(function () {
-	  return $.map(self.fields(), function (field) { return field.name()});
+	return $.map(self.fields(), function (field) { return field.name() });
   });
 
   self.resultsetShowFieldList = ko.observable(true);
@@ -175,9 +188,25 @@ var Dashboard = function (vm, dashboard) {
     });
     return _facet;
   }   
+  
+  self.updateFields = function(database, table) {
+    $.post("/impala/dashboard/get_fields", {
+    	"database": self.properties()[0].database(),
+    	"table": self.properties()[0].table()
+    }, function (data) {
+      if (data.status == 0) {
+        self.properties()[0].fields.removeAll();
+        self.resultsetSelectedFields.removeAll();
+    	$.each(data.fields, function (index, field) {
+    	  self.properties()[0].fields.push(ko.mapping.fromJS(field));
+    	  self.resultsetSelectedFields.push(field.name);
+      	});        
+      }
+    }).fail(function (xhr, textStatus, errorThrown) {});
+  }  
 }
 
-var ImpalaDashboardViewModel = function (query_json, dashboard_json) {
+var ImpalaDashboardViewModel = function (query_json, dashboard_json, initial_json) {
     var self = this;
 
     self.isEditing = ko.observable(false);
@@ -192,6 +221,7 @@ var ImpalaDashboardViewModel = function (query_json, dashboard_json) {
 
     self.query = new Query(self, query_json);
     self.dashboard = new Dashboard(self, dashboard_json);
+    self.initial = initial_json;
 
     self.results = ko.observableArray([]);
     self.results_facet = ko.observableArray([]);
@@ -302,5 +332,4 @@ var ImpalaDashboardViewModel = function (query_json, dashboard_json) {
     self.draggableLine = ko.observable(bareWidgetBuilder("Line Chart", "line-widget"));
     self.draggablePie = ko.observable(bareWidgetBuilder("Pie Chart", "pie-widget"));
     self.draggableFilter = ko.observable(bareWidgetBuilder("Filter Bar", "filter-widget"));
-  
 };