Browse Source

HUE-7944 [editor] Provide an aync table sample api

Romain Rigaux 7 năm trước cách đây
mục cha
commit
982874a41b

+ 23 - 11
apps/beeswax/src/beeswax/api.py

@@ -33,7 +33,7 @@ from desktop.lib.exceptions_renderable import PopupException
 from desktop.lib.i18n import force_unicode
 from desktop.lib.parameterization import substitute_variables
 from metastore import parser
-from notebook.models import escape_rows
+from notebook.models import escape_rows, MockedDjangoRequest, make_notebook
 
 import beeswax.models
 
@@ -656,25 +656,37 @@ def get_sample_data(request, database, table, column=None):
   return JsonResponse(response)
 
 
-def _get_sample_data(db, database, table, column):
+def _get_sample_data(db, database, table, column, async=False):
   table_obj = db.get_table(database, table)
   if table_obj.is_impala_only and db.client.query_server['server_name'] != 'impala':
     query_server = get_query_server_config('impala')
     db = dbms.get(db.client.user, query_server)
 
-  sample_data = db.get_sample(database, table_obj, column)
+  sample_data = db.get_sample(database, table_obj, column, generate_sql_only=async)
   response = {'status': -1}
 
   if sample_data:
-    sample = escape_rows(sample_data.rows(), nulls_only=True)
-    if column:
-      sample = set([row[0] for row in sample])
-      sample = [[item] for item in sorted(list(sample))]
+    if async:
+      notebook = make_notebook(
+          name=_('Table sample for `%(database)s`.`%(table)s`.`%(column)s`') % {'database': database, 'table': table, 'column': column},
+          editor_type=db.server_name,
+          statement=sample_data,
+          status='ready',
+          is_task=False
+      )
+      task = notebook.execute(request=MockedDjangoRequest(user=db.client.user), batch=False)
+      response['history_id'] = task['history_id']
+      response['history_uuid'] = task['history_uuid']
+    else:
+      sample = escape_rows(sample_data.rows(), nulls_only=True)
+      if column:
+        sample = set([row[0] for row in sample])
+        sample = [[item] for item in sorted(list(sample))]
 
-    response['status'] = 0
-    response['headers'] = sample_data.cols()
-    response['full_headers'] = sample_data.full_cols()
-    response['rows'] = sample
+      response['status'] = 0
+      response['headers'] = sample_data.cols()
+      response['full_headers'] = sample_data.full_cols()
+      response['rows'] = sample
   else:
     response['message'] = _('Failed to get sample data.')
 

+ 4 - 4
apps/beeswax/src/beeswax/server/dbms.py

@@ -358,7 +358,7 @@ class HiveServer2Dbms(object):
     return resp
 
 
-  def get_sample(self, database, table, column=None, nested=None, limit=100, async=False):
+  def get_sample(self, database, table, column=None, nested=None, limit=100, generate_sql_only=False):
     result = None
     hql = None
 
@@ -378,10 +378,10 @@ class HiveServer2Dbms(object):
       # TODO: Add nested select support for HS2
 
     if hql:
-      query = hql_query(hql)
-      if async:
-        return self.execute_and_watch(query)
+      if generate_sql_only:
+        return hql
       else:
+        query = hql_query(hql)
         handle = self.execute_and_wait(query, timeout_sec=5.0)
 
         if handle:

+ 3 - 3
desktop/libs/indexer/src/indexer/templates/importer.mako

@@ -367,6 +367,9 @@ ${ assist.assistPanel() }
       <!-- /ko -->
       <!-- ko ifnot: createWizard.isGuessingFieldTypes -->
       <h4>${_('Preview')}</h4>
+      <!-- ko if: createWizard.source.inputFormat() == 'query' -->
+        ${ _('Add sample data') } <i class="fa fa-fw fa-play"></i>
+      <!-- /ko -->
       <div class="card-body">
         <div style="overflow: auto">
           <table class="table table-condensed table-preview">
@@ -382,9 +385,6 @@ ${ assist.assistPanel() }
               <td data-bind="truncatedText: $data"></td>
             </tr>
             </tbody>
-            <!-- ko if: createWizard.source.inputFormat() == 'query' -->
-              ${ _('Add sample data') } <i class="fa fa-fw fa-play"></i>
-            <!-- /ko -->
           </table>
         </div>
       </div>

+ 2 - 1
desktop/libs/notebook/src/notebook/api.py

@@ -586,8 +586,9 @@ def get_sample_data(request, server=None, database=None, table=None, column=None
   # Passed by check_document_access_permission but unused by APIs
   notebook = json.loads(request.POST.get('notebook', '{}'))
   snippet = json.loads(request.POST.get('snippet', '{}'))
+  async = json.loads(request.POST.get('async', 'false'))
 
-  sample_data = get_api(request, snippet).get_sample_data(snippet, database, table, column)
+  sample_data = get_api(request, snippet).get_sample_data(snippet, database, table, column, async=async)
   response.update(sample_data)
 
   response['status'] = 0

+ 2 - 0
desktop/libs/notebook/src/notebook/connectors/base.py

@@ -327,6 +327,8 @@ class Api(object):
   def get_jobs(self, notebook, snippet, logs):
     return []
 
+  def get_sample_data(self, snippet, database=None, table=None, column=None, async=False): raise NotImplementedError()
+
   def export_data_as_hdfs_file(self, snippet, target_file, overwrite): raise NotImplementedError()
 
   def export_data_as_table(self, notebook, snippet, destination, is_temporary=False, location=None): raise NotImplementedError()

+ 2 - 2
desktop/libs/notebook/src/notebook/connectors/hiveserver2.py

@@ -459,10 +459,10 @@ class HS2Api(Api):
 
 
   @query_error_handler
-  def get_sample_data(self, snippet, database=None, table=None, column=None):
+  def get_sample_data(self, snippet, database=None, table=None, column=None, async=False):
     try:
       db = self._get_db(snippet)
-      return _get_sample_data(db, database, table, column) # TODO async in all signatures
+      return _get_sample_data(db, database, table, column, async)
     except QueryServerException, ex:
       raise QueryError(ex.message)
 

+ 1 - 1
desktop/libs/notebook/src/notebook/connectors/jdbc.py

@@ -158,7 +158,7 @@ class JdbcApi(Api):
     return response
 
   @query_error_handler
-  def get_sample_data(self, snippet, database=None, table=None, column=None):
+  def get_sample_data(self, snippet, database=None, table=None, column=None, async=False):
     if self.db is None:
       raise AuthenticationRequired()
 

+ 1 - 1
desktop/libs/notebook/src/notebook/connectors/rdbms.py

@@ -151,7 +151,7 @@ class RdbmsApi(Api):
 
 
   @query_error_handler
-  def get_sample_data(self, snippet, database=None, table=None, column=None):
+  def get_sample_data(self, snippet, database=None, table=None, column=None, async=False):
     query_server = dbms.get_query_server_config(server=self.interpreter)
     db = dbms.get(self.user, query_server)
 

+ 1 - 1
desktop/libs/notebook/src/notebook/connectors/solr.py

@@ -159,7 +159,7 @@ class SolrApi(Api):
 
 
   @query_error_handler
-  def get_sample_data(self, snippet, database=None, table=None, column=None):
+  def get_sample_data(self, snippet, database=None, table=None, column=None, async=False):
     from search.conf import SOLR_URL
     db = NativeSolrApi(SOLR_URL.get(), self.user)
 

+ 11 - 0
desktop/libs/notebook/src/notebook/models.py

@@ -192,6 +192,17 @@ def make_notebook2(name='Browse', description='', is_saved=False, snippets=None)
   return editor
 
 
+class MockedDjangoRequest():
+
+  def __init__(self, user, get=None, post=None, method='POST'):
+    self.user = user
+    self.jt = None
+    self.GET = get if get is not None else {'format': 'json'}
+    self.POST = post if post is not None else {}
+    self.REQUEST = {}
+    self.method = method
+
+
 def import_saved_beeswax_query(bquery):
   design = bquery.get_design()