Skip to content
This repository has been archived by the owner on Jan 28, 2021. It is now read-only.

Commit

Permalink
Adding query plan, query time, and total time to the query model
Browse files Browse the repository at this point in the history
  • Loading branch information
vegitron committed Jul 20, 2015
1 parent 40e2a5b commit 166ac98
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 9 deletions.
8 changes: 8 additions & 0 deletions sqlshare_rest/backend/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ class DBInterface(object):
def __init__(self):
self.username = None

def get_query_plan(self, sql, user):
"""
This should return a string describing the complexity of the given
SQL statement. By default it's empty, only implemented in some DB
backends.
"""
return ""

def run_query(self, sql, user, params=None, return_cursor=False):
self._not_implemented("run_query")

Expand Down
16 changes: 16 additions & 0 deletions sqlshare_rest/backend/mssql.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,22 @@ def create_view(self, name, sql, user, column_names=None):
result = self.run_query(count_sql, user)
return result[0][0]

def get_query_plan(self, sql, user):
connection = self.get_connection_for_user(user)
cursor = connection.cursor()
cursor.execute("SET SHOWPLAN_XML ON")
print "Turned on SHOWPLAN_XML"
try:
cursor.execute(sql)
data = cursor.fetchall()[0][0]
except Exception:
raise
finally:
cursor.execute("SET SHOWPLAN_XML OFF")

cursor.close()
return data

def run_query(self, sql, user, params=None, return_cursor=False):
connection = self.get_connection_for_user(user)
cursor = connection.cursor()
Expand Down
4 changes: 4 additions & 0 deletions sqlshare_rest/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,10 @@ class Query(models.Model):
rows_total = models.IntegerField(null=True)
process_queue_id = models.IntegerField(null=True)
terminated = models.BooleanField(default=False)
preview_content = models.TextField(null=True)
query_plan = models.TextField(null=True)
query_time = models.FloatField(null=True)
total_time = models.FloatField(null=True)

def save(self, *args, **kwargs):
super(Query, self).save(*args, **kwargs)
Expand Down
35 changes: 31 additions & 4 deletions sqlshare_rest/util/query_queue.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from sqlshare_rest.logger import getLogger
import atexit
import signal
import json
import time
import sys
import os
Expand Down Expand Up @@ -71,6 +72,19 @@ def start_query(query, background=True):
if background:
sys.exit(0)

def get_column_names_from_cursor(cursor):
index = 0
names = []
for col in cursor.description:
index += 1
column_name = col[0]
if column_name == "":
column_name = "COLUMN%s" % index

names.append(column_name)

return names

def process_query(query_id):
logger = getLogger(__name__)
query = Query.objects.get(pk=query_id)
Expand Down Expand Up @@ -99,16 +113,29 @@ def process_query(query_id):
backend = get_backend()
try:
start = timezone.now()
query_plan = backend.get_query_plan(query.sql, user)

t1 = time.time()
cursor = backend.run_query(query.sql,
user,
return_cursor=True)

t2 = time.time()
name = "query_%s" % query.pk
try:
create_table = backend.create_table_from_query_result
row_count = create_table(name, cursor)
backend.add_owner_read_access_to_query(query.pk,
user)
all_data = []
for row in cursor:
all_data.append(list(row))

columns = get_column_names_from_cursor(cursor)
formatted = json.dumps({"columns": columns, "data": all_data})
query.preview_content = formatted
t3 = time.time()

query.query_time = t2-t1
query.total_time = t3-t1
query.query_plan = query_plan
query.save()

end = timezone.now()
except:
Expand Down
9 changes: 4 additions & 5 deletions sqlshare_rest/views/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,10 @@ def _get_query(request, id, query):
data = query.json_data(request)
user = get_user(request)

sample_data, columns = get_sample_data_for_query(query,
user.username)

data["sample_data"] = sample_data
data["columns"] = columns
if query.preview_content:
preview_data = json.loads(query.preview_content)
data["sample_data"] = preview_data["data"]
data["columns"] = preview_data["columns"]

response = HttpResponse(json.dumps(data, default=json_serializer))

Expand Down

0 comments on commit 166ac98

Please sign in to comment.