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

[beeswax] Add get_indexes API endpoint

GET beeswax/api/table/(?P<database>\w+)/(?P<table>\w+)/indexes

{
	"status": 0,
	"headers": ["idx_name", "tab_name", "col_names", "idx_tab_name", "idx_type", "comment"],
	"error_message": "",
	"rows": [
		["web_logs_id_idx     ", "web_logs            ", "id                  ", "default__web_logs_web_logs_id_idx__", "compact             ", ""],
		["web_logs_client_ip_idx", "web_logs            ", "client_ip           ", "default__web_logs_web_logs_client_ip_idx__", "compact             ", ""],
		["web_logs_region_code_idx", "web_logs            ", "client_ip           ", "default__web_logs_web_logs_region_code_idx__", "compact             ", ""]
	]
}
Jenny Kim 10 жил өмнө
parent
commit
f5f6eb2

+ 20 - 0
apps/beeswax/src/beeswax/api.py

@@ -684,6 +684,26 @@ def get_sample_data(request, database, table):
   return JsonResponse(response)
 
 
+def get_indexes(request, database, table):
+  query_server = dbms.get_query_server_config(get_app_name(request))
+  db = dbms.get(request.user, query_server)
+  response = {'status': -1, 'error_message': ''}
+
+  try:
+    indexes = db.get_indexes(database, table)
+    if indexes:
+      response['status'] = 0
+      response['headers'] = indexes.cols()
+      response['rows'] = escape_rows(indexes.rows(), nulls_only=True)
+    else:
+      response['error_message'] = _('Index data took too long to be generated')
+  except Exception, ex:
+    error_message, logs = dbms.expand_exception(ex, db)
+    response['error_message'] = error_message
+
+  return JsonResponse(response)
+
+
 def get_query_form(request):
   try:
     try:

+ 12 - 0
apps/beeswax/src/beeswax/server/dbms.py

@@ -760,6 +760,18 @@ class HiveServer2Dbms(object):
     return self.execute_query(query, design)
 
 
+  def get_indexes(self, db_name, table_name):
+    hql = 'SHOW FORMATTED INDEXES ON `%(table)s` IN `%(database)s`' % {'table': table_name, 'database': db_name}
+
+    query = hql_query(hql)
+    handle = self.execute_and_wait(query, timeout_sec=15.0)
+
+    if handle:
+      result = self.fetch(handle, rows=5000)
+
+    return result
+
+
   def explain(self, query):
     return self.client.explain(query)
 

+ 17 - 0
apps/beeswax/src/beeswax/tests.py

@@ -1891,6 +1891,23 @@ for x in sys.stdin:
     assert_true("fields" in json_resp)
 
 
+  def test_get_indexes(self):
+    table_name = 'indexed_table'
+
+    hql = """
+      CREATE TABLE `%(db)s`.`%(table)s` (id INT, name STRING, age INT, state STRING);
+      CREATE INDEX `id_idx` ON TABLE `%(db)s`.`%(table)s` (`id`) AS 'COMPACT' WITH DEFERRED REBUILD;
+      CREATE INDEX `state_idx` ON TABLE `%(db)s`.`%(table)s` (`state`) AS 'COMPACT' WITH DEFERRED REBUILD;
+    """ % {'db': self.db_name, 'table': table_name}
+    _make_query(self.client, hql, wait=True, local=False, max=180.0, database=self.db_name)
+
+    resp = self.client.get(reverse("beeswax:get_indexes", kwargs={'database': self.db_name, 'table': table_name}))
+    json_resp = json.loads(resp.content)
+    assert_true('headers' in json_resp, json_resp)
+    assert_true('rows' in json_resp, json_resp)
+    assert_equal(2, len(json_resp['rows']), json_resp['rows'])
+
+
   def test_databases_quote(self):
     c = self.client
     db_name = '__%s' % self.db_name

+ 2 - 0
apps/beeswax/src/beeswax/urls.py

@@ -86,6 +86,8 @@ urlpatterns += patterns(
 
   url(r'^api/table/(?P<database>\w+)/(?P<table>\w+)$', 'describe_table', name='describe_table'),
   url(r'^api/table/(?P<database>\w+)/(?P<table>\w+)/sample$', 'get_sample_data', name='get_sample_data'),
+  url(r'^api/table/(?P<database>\w+)/(?P<table>\w+)/indexes$', 'get_indexes', name='get_indexes'),
+
   url(r'^api/analyze/(?P<database>\w+)/(?P<table>\w+)/(?P<columns>\w+)?$', 'analyze_table', name='analyze_table'),
   url(r'^api/table/(?P<database>\w+)/(?P<table>\w+)/stats/(?P<column>\w+)?$', 'get_table_stats', name='get_table_stats'),
   url(r'^api/table/(?P<database>\w+)/(?P<table>\w+)/terms/(?P<column>\w+)/(?P<prefix>\w+)?$', 'get_top_terms', name='get_top_terms'),