Эх сурвалжийг харах

HUE-8740 [sql] sqlalchemy add basic support for table browser.

jdesjean 6 жил өмнө
parent
commit
c114f275c8

+ 2 - 6
desktop/core/src/desktop/js/api/apiHelper.js

@@ -1570,11 +1570,7 @@ class ApiHelper {
     if (options.path.length === 1) {
       url = '/metastore/databases/' + options.path[0] + '/metadata';
     } else {
-      url =
-        '/' +
-        (options.sourceType === 'hive' ? 'beeswax' : options.sourceType) +
-        '/api/table/' +
-        options.path[0];
+      url = '/notebook/api/describe/' + options.path[0]
 
       if (options.path.length > 1) {
         url += '/' + options.path[1] + '/';
@@ -1591,7 +1587,7 @@ class ApiHelper {
       source_type: options.sourceType
     };
 
-    const request = self[options.path.length < 3 ? 'simplePost' : 'simpleGet'](url, data, {
+    const request = self['simplePost'](url, data, {
       silenceErrors: options.silenceErrors,
       successCallback: function(response) {
         if (options.path.length === 1) {

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

@@ -832,3 +832,14 @@ def _get_statement_from_file(user, fs, snippet):
     script_path = script_path.replace('hdfs://', '')
     if fs.do_as_user(user, fs.isfile, script_path):
       return fs.do_as_user(user, fs.read, script_path, 0, 16 * 1024 ** 2)
+
+def describe(request, database, table):
+  response = {'status': -1, 'message': ''}
+  notebook = json.loads(request.POST.get('notebook', '{}'))
+  source_type = request.POST.get('source_type', '')
+  snippet = {'type': source_type}
+
+  describe = get_api(request, snippet).describe(notebook, snippet, database, table)
+  response.update(describe)
+
+  return JsonResponse(response)

+ 50 - 6
desktop/libs/notebook/src/notebook/connectors/base.py

@@ -476,6 +476,56 @@ class Api(object):
 
   def statement_similarity(self, notebook, snippet, source_platform, target_platform): raise NotImplementedError()
 
+  def describe(self, notebook, snippet, database=None, table=None, column=None):
+    if column:
+      response = self.describe_column(notebook, snippet, database=database, table=table, column=column)
+    elif table:
+      response = {
+          'status': 0,
+          'name': table or '',
+          'partition_keys': [],
+          'cols': [],
+          'path_location': '',
+          'hdfs_link': '',
+          'comment': '',
+          'is_view': False,
+          'properties': [],
+          'details': {'properties': {'table_type': ''}, 'stats': {}},
+          'stats': []
+      }
+      describe_table = self.describe_table(notebook, snippet, database, table)
+      response.update(describe_table)
+    else:
+      response = {
+        'status': 0,
+        'owner_name': '',
+        'owner_type': '',
+        'parameters': '',
+        'hdfs_link': '',
+        'message': ''
+      }
+      describe_database = self.describe_database(notebook, snippet, database)
+      response.update(describe_database)
+    return response
+
+  def describe_column(self, notebook, snippet, database=None, table=None, column=None):
+    return []
+
+  def describe_table(self, notebook, snippet, database=None, table=None):
+    response = {}
+    autocomplete = self.autocomplete(snippet, database=database, table=table)
+    response['cols'] = autocomplete['extended_columns'] if autocomplete and autocomplete.get('extended_columns') else [],
+    return response
+
+  def describe_database(self, notebook, snippet, database=None):
+    return {}
+
+def _get_snippet_name(notebook, unique=False, table_format=False):
+  name = (('%(name)s' + ('-%(id)s' if unique else '') if notebook.get('name') else '%(type)s-%(id)s') % notebook)
+  if table_format:
+    name = re.sub('[-|\s:]', '_', name)
+  return name
+
 class ResultWrapper():
   def __init__(self, api, notebook, snippet, callback=None):
     self.api = api
@@ -527,9 +577,3 @@ class ResultWrapper():
     if self.should_close:
       self.should_close = False
       self.api.close_statement(self.notebook, self.snippet)
-
-def _get_snippet_name(notebook, unique=False, table_format=False):
-  name = (('%(name)s' + ('-%(id)s' if unique else '') if notebook.get('name') else '%(type)s-%(id)s') % notebook)
-  if table_format:
-    name = re.sub('[-|\s:]', '_', name)
-  return name

+ 26 - 0
desktop/libs/notebook/src/notebook/connectors/hiveserver2.py

@@ -889,3 +889,29 @@ DROP TABLE IF EXISTS `%(table)s`;
     query_plan_re = "Query \(id=%(query_id)s\):.+?Execution Profile %(query_id)s" % {'query_id': query_id}
     query_plan_match = re.search(query_plan_re, profile, re.MULTILINE | re.DOTALL)
     return query_plan_match.group() if query_plan_match else None
+
+  def describe_column(self, notebook, snippet, database=None, table=None, column=None):
+    db = self._get_db(snippet, self.cluster)
+    return db.get_table_columns_stats(database, table, column)
+
+  def describe_table(self, notebook, snippet, database=None, table=None):
+    db = self._get_db(snippet, self.cluster)
+    tb = db.get_table(database, table)
+    return {
+      'status': 0,
+      'name': tb.name,
+      'partition_keys': [{'name': part.name, 'type': part.type} for part in tb.partition_keys],
+      'cols': [{'name': col.name, 'type': col.type, 'comment': col.comment} for col in tb.cols],
+      'path_location': tb.path_location,
+      'hdfs_link': tb.hdfs_link,
+      'comment': tb.comment,
+      'is_view': tb.is_view,
+      'properties': tb.properties,
+      'details': tb.details,
+      'stats': tb.stats
+    }
+    
+
+  def describe_database(self, notebook, snippet, database=None):
+    db = self._get_db(snippet, self.cluster)
+    return db.get_database(database)

+ 7 - 0
desktop/libs/notebook/src/notebook/urls.py

@@ -97,3 +97,10 @@ urlpatterns += [
   url(r'^api/sample/(?P<server>[\w_\-/]+)/(?P<database>[\w._\-0-9]+)/(?P<table>\w+)/?$', notebook_api.get_sample_data, name='api_sample_data'),
   url(r'^api/sample/(?P<server>[\w_\-/]+)/(?P<database>[\w._\-0-9]+)/(?P<table>\w+)/(?P<column>\w+)/?$', notebook_api.get_sample_data, name='api_sample_data_column'),
 ]
+
+# Table API
+urlpatterns += [
+  url(r'^api/describe/(?P<database>\w+)/?$', notebook_api.describe, name='api_describe_database'),
+  url(r'^api/describe/(?P<database>\w+)/(?P<table>[\w_\-]+)/?$', notebook_api.describe, name='api_describe_table'),
+  url(r'^api/describe/(?P<database>\w+)/(?P<table>\w+)/stats/(?P<column>\w+)?$', notebook_api.describe, name='api_describe_column'),
+]