Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I have updated the query for issue #3132 to match version 10. #5909

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 55 additions & 6 deletions redash/query_runner/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
import importlib
import logging
import sys
import pystache
from funcy import distinct

from redash.query_runner import *
from redash.utils import json_dumps, json_loads
from redash.utils import json_dumps, json_loads, mustache_render
from redash import models
from RestrictedPython import compile_restricted
from RestrictedPython.Guards import safe_builtins, guarded_iter_unpack_sequence, guarded_unpack_sequence
Expand All @@ -20,6 +22,29 @@

logger = logging.getLogger(__name__)

def get_query(query_id):
try:
query = models.Query.get_by_id(query_id)
except models.NoResultFound:
raise Exception("Query id %s does not exist." % query_id)
return query

def _collect_key_names(nodes):
keys = []
for node in nodes._parse_tree:
if isinstance(node, pystache.parser._EscapeNode):
keys.append(node.key)
elif isinstance(node, pystache.parser._SectionNode):
keys.append(node.key)
keys.extend(_collect_key_names(node.parsed))

return distinct(keys)

def _collect_query_parameters(query):
nodes = pystache.parse(query)
keys = _collect_key_names(nodes)
return keys


class CustomPrint(object):
"""CustomPrint redirect "print" calls to be sent as "log" on the result object."""
Expand Down Expand Up @@ -248,10 +273,11 @@ def get_query_result(query_id):
Parameters:
:query_id integer: ID of existing query
"""
try:
query = models.Query.get_by_id(query_id)
except models.NoResultFound:
raise Exception("Query id %s does not exist." % query_id)
# try:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably not good to leave commented out code around like this. 😉

# query = models.Query.get_by_id(query_id)
# except models.NoResultFound:
# raise Exception("Query id %s does not exist." % query_id)
query = get_query(query_id)

if query.latest_query_data is None:
raise Exception("Query does not have results yet.")
Expand All @@ -260,7 +286,29 @@ def get_query_result(query_id):
raise Exception("Query does not have results yet.")

return query.latest_query_data.data


@staticmethod
def execute_by_query_id(query_id, params=None):
"""Run query from specific query_id.
Parameters:
:query_id int: Query id to run
:params dict: Params for bind to query
"""
query = get_query(query_id)
query_text = query.query_text
query_params = set(_collect_query_parameters(query_text))
if params is None:
query_text = query.query_text
missing_params = set(query_params)
else:
query_text = mustache_render(query.query_text, params)
missing_params = set(query_params) - set(params.keys())
if len(missing_params) > 0:
raise Exception('Missing parameter value for: {}'.format(", ".join(missing_params)))
data, error = query.data_source.query_runner.run_query(query_text, None)
if error is not None:
raise Exception(error)
return json_loads(data)
def dataframe_to_result(self, result, df):

result["rows"] = df.to_dict("records")
Expand Down Expand Up @@ -322,6 +370,7 @@ def run_query(self, query, user):
restricted_globals["get_source_schema"] = self.get_source_schema
restricted_globals["get_current_user"] = self.get_current_user
restricted_globals["execute_query"] = self.execute_query
restricted_globals["execute_by_query_id"] = self.execute_by_query_id
restricted_globals["add_result_column"] = self.add_result_column
if pandas_installed:
restricted_globals["dataframe_to_result"] = self.dataframe_to_result
Expand Down