Bläddra i källkod

HUE-6079 [metastore] Make load data work with responsive

Both with regular table and partitioned tables.
Slight UX clean-up in old js/form code.
Romain Rigaux 8 år sedan
förälder
incheckning
81355d91b9

+ 8 - 5
apps/beeswax/src/beeswax/server/dbms.py

@@ -536,7 +536,7 @@ class HiveServer2Dbms(object):
     return self.execute_statement(hql)
 
 
-  def load_data(self, database, table, form, design):
+  def load_data(self, database, table, form, design, generate_ddl_only=False):
     hql = "LOAD DATA INPATH"
     hql += " '%s'" % form.cleaned_data['path']
     if form.cleaned_data['overwrite']:
@@ -551,11 +551,14 @@ class HiveServer2Dbms(object):
       hql += ", ".join(vals)
       hql += ")"
 
-    query = hql_query(hql, database)
-    design.data = query.dumps()
-    design.save()
+    if generate_ddl_only:
+      return hql
+    else:
+      query = hql_query(hql, database)
+      design.data = query.dumps()
+      design.save()
 
-    return self.execute_query(query, design)
+      return self.execute_query(query, design)
 
 
   def drop_tables(self, database, tables, design, skip_trash=False, generate_ddl_only=False):

+ 1 - 0
apps/metastore/src/metastore/forms.py

@@ -45,6 +45,7 @@ class LoadDataForm(forms.Form):
   """Form used for loading data into an existing table."""
   path = PathField(label=_t("Path"))
   overwrite = forms.BooleanField(required=False, initial=False, label=_t("Overwrite?"))
+  is_embeddable = forms.BooleanField(required=False, initial=False)
 
   def __init__(self, table_obj, *args, **kwargs):
     """

+ 3 - 3
apps/metastore/src/metastore/templates/metastore.mako

@@ -635,14 +635,14 @@ ${ components.menubar() }
     % if has_write_access:
       <a class="inactive-action" href="#" data-bind="tooltip: { placement: 'bottom', delay: 750 }, click: showImportData, visible: tableDetails() && ! tableDetails().is_view" title="${_('Import Data')}"><i class="fa fa-upload fa-fw"></i></a>
     % endif
-    % if has_write_access:
-      <a class="inactive-action" href="#dropSingleTable" data-toggle="modal" data-bind="tooltip: { placement: 'bottom', delay: 750 }, attr: { 'title' : tableDetails() && tableDetails().is_view ? '${_('Drop View')}' : '${_('Drop Table')}' }"><i class="fa fa-times fa-fw"></i></a>
-    % endif
     <!-- ko if: tableDetails() -->
       <!-- ko if: tableDetails().partition_keys.length -->
       <a class="inactive-action" data-bind="tooltip: { placement: 'bottom', delay: 750 }, attr: { 'href': '/metastore/table/' + database.name + '/' + name + '/partitions' }" title="${_('Show Partitions')}"><i class="fa fa-sitemap fa-fw"></i></a>
       <!-- /ko -->
     <!-- /ko -->
+    % if has_write_access:
+      <a class="inactive-action" href="#dropSingleTable" data-toggle="modal" data-bind="tooltip: { placement: 'bottom', delay: 750 }, attr: { 'title' : tableDetails() && tableDetails().is_view ? '${_('Drop View')}' : '${_('Drop Table')}' }"><i class="fa fa-times fa-fw"></i></a>
+    % endif
     <!-- /ko -->
     <!-- /ko -->
   </div>

+ 27 - 16
apps/metastore/src/metastore/templates/popups/load_data.mako

@@ -26,6 +26,7 @@ from django.utils.translation import ugettext as _
       <h2 class="modal-title">${_('Import Data')}</h2>
     </div>
     <div class="modal-body">
+        <input id="load_data_is_embeddable" type="hidden" name="is_embeddable" value="false">
 
         <div class="control-group">
             ${comps.bootstrapLabel(load_form["path"])}
@@ -47,7 +48,7 @@ from django.utils.translation import ugettext as _
 
         <div class="control-group">
           <div class="controls">
-            <label class="checkbox">
+            <label class="checkbox inline-block">
                 <input type="checkbox" name="overwrite"/> ${_('Overwrite existing data')}
               </label>
             </div>
@@ -130,22 +131,32 @@ from django.utils.translation import ugettext as _
     }
 
     $("#load-data-submit-btn").click(function (e) {
+      if (IS_HUE_4) {
+        $("#load_data_is_embeddable").val("true");
+      }
       $.post("${ url('metastore:load_table', database=database, table=table.name) }",
-              $("#load-data-form").serialize(),
-              function (response) {
-                $("#load-data-submit-btn").button('reset');
-                if (response['status'] != 0) {
-                  if (response['status'] == 1) {
-                    $('#load-data-error').html(response['data']);
-                    $('#load-data-error').show();
-                  } else {
-                    $('#import-data-modal').html(response['data']);
-                  }
-                } else {
-                  window.location.replace(response['data']);
-                }
-              }
-      );
+        $("#load-data-form").serialize(),
+        function (response) {
+          if (response['status'] != 0) {
+            if (response['status'] == 1) {
+              $('#load-data-error').html(response['data']);
+              $('#load-data-error').show();
+            } else {
+              $('#import-data-modal').html(response['data']);
+            }
+          } else {
+            if (IS_HUE_4) {
+              huePubSub.publish('notebook.task.submitted', response.history_uuid);
+              $("#import-data-modal").modal("hide");
+            } else {
+              window.location.replace(response['data']);
+            }
+          }
+        }
+      ).always(function () {
+        $("#load-data-submit-btn").button('reset');
+        $("#load-data-submit-btn").removeAttr("disabled");
+      });
     });
   });
 </script>

+ 21 - 5
apps/metastore/src/metastore/views.py

@@ -37,7 +37,7 @@ from beeswax.server import dbms
 from beeswax.server.dbms import get_query_server_config
 from filebrowser.views import location_to_url
 from metadata.conf import has_optimizer, has_navigator, get_optimizer_url, get_navigator_url
-from notebook.connectors.base import Notebook
+from notebook.connectors.base import Notebook, QueryError
 from notebook.models import make_notebook
 
 from metastore.forms import LoadDataForm, DbForm
@@ -439,12 +439,28 @@ def load_table(request, database, table):
 
     if load_form.is_valid():
       on_success_url = reverse('metastore:describe_table', kwargs={'database': database, 'table': table.name})
+      generate_ddl_only = request.POST.get('is_embeddable', 'false') == 'true'
       try:
         design = SavedQuery.create_empty(app_name='beeswax', owner=request.user, data=hql_query('').dumps())
-        query_history = db.load_data(database, table, load_form, design)
-        url = reverse('beeswax:watch_query_history', kwargs={'query_history_id': query_history.id}) + '?on_success_url=' + on_success_url
-        response['status'] = 0
-        response['data'] = url
+        query_history = db.load_data(database, table, load_form, design, generate_ddl_only=generate_ddl_only)
+        if generate_ddl_only:
+          job = make_notebook(
+            name='Execute and watch',
+            editor_type='hive',
+            statement=query_history.strip(),
+            status='ready',
+            database=database,
+            on_success_url='assist.db.refresh',
+            is_task=True
+          )
+          response = job.execute(request)
+        else:
+          url = reverse('beeswax:watch_query_history', kwargs={'query_history_id': query_history.id}) + '?on_success_url=' + on_success_url
+          response['status'] = 0
+          response['data'] = url
+      except QueryError, ex:
+        response['status'] = 1
+        response['data'] = _("Can't load the data: ") + ex.message
       except Exception, e:
         response['status'] = 1
         response['data'] = _("Can't load the data: ") + str(e)