Stabilizing master (#2478)

This commit is contained in:
Maxime Beauchemin 2017-03-27 17:52:17 -07:00 committed by GitHub
parent 7cc2c930ed
commit c3015583ce
4 changed files with 29 additions and 31 deletions

View File

@ -21,10 +21,7 @@ from flask_babel import lazy_gettext as _
from superset import db, utils, import_util from superset import db, utils, import_util
from superset.connectors.base import BaseDatasource, BaseColumn, BaseMetric from superset.connectors.base import BaseDatasource, BaseColumn, BaseMetric
from superset.utils import ( from superset.utils import DTTM_ALIAS, QueryStatus
wrap_clause_in_parens,
DTTM_ALIAS, QueryStatus
)
from superset.models.helpers import QueryResult from superset.models.helpers import QueryResult
from superset.models.core import Database from superset.models.core import Database
from superset.jinja_context import get_template_processor from superset.jinja_context import get_template_processor
@ -286,7 +283,7 @@ class SqlaTable(Model, BaseDatasource):
cols = {col.column_name: col for col in self.columns} cols = {col.column_name: col for col in self.columns}
target_col = cols[column_name] target_col = cols[column_name]
tbl = table(self.table_name) tbl = self.get_sqla_table()
qry = ( qry = (
select([target_col.sqla_col]) select([target_col.sqla_col])
.select_from(tbl) .select_from(tbl)
@ -305,10 +302,7 @@ class SqlaTable(Model, BaseDatasource):
engine, compile_kwargs={"literal_binds": True}, ), engine, compile_kwargs={"literal_binds": True}, ),
) )
df = pd.read_sql_query( df = pd.read_sql_query(sql=sql, con=engine)
sql=sql,
con=engine
)
return [row[0] for row in df.to_records(index=False)] return [row[0] for row in df.to_records(index=False)]
def get_template_processor(self, **kwargs): def get_template_processor(self, **kwargs):
@ -316,13 +310,25 @@ class SqlaTable(Model, BaseDatasource):
table=self, database=self.database, **kwargs) table=self, database=self.database, **kwargs)
def get_query_str(self, **kwargs): def get_query_str(self, **kwargs):
engine = self.database.get_sqla_engine()
qry = self.get_sqla_query(**kwargs) qry = self.get_sqla_query(**kwargs)
sql = str(qry.compile(kwargs['engine'])) sql = str(
qry.compile(
engine,
compile_kwargs={"literal_binds": True}
)
)
logging.info(sql) logging.info(sql)
sql = sqlparse.format(sql, reindent=True) sql = sqlparse.format(sql, reindent=True)
sql = self.database.db_engine_spec.sql_preprocessor(sql) sql = self.database.db_engine_spec.sql_preprocessor(sql)
return sql return sql
def get_sqla_table(self):
tbl = table(self.table_name)
if self.schema:
tbl.schema = self.schema
return tbl
def get_sqla_query( # sqla def get_sqla_query( # sqla
self, self,
groupby, metrics, groupby, metrics,
@ -430,14 +436,12 @@ class SqlaTable(Model, BaseDatasource):
select_exprs += metrics_exprs select_exprs += metrics_exprs
qry = sa.select(select_exprs) qry = sa.select(select_exprs)
tbl = table(self.table_name)
if self.schema:
tbl.schema = self.schema
# Supporting arbitrary SQL statements in place of tables # Supporting arbitrary SQL statements in place of tables
if self.sql: if self.sql:
from_sql = template_processor.process_template(self.sql) from_sql = template_processor.process_template(self.sql)
tbl = TextAsFrom(sa.text(from_sql), []).alias('expr_qry') tbl = TextAsFrom(sa.text(from_sql), []).alias('expr_qry')
else:
tbl = self.get_sqla_table()
if not columns: if not columns:
qry = qry.group_by(*groupby_exprs) qry = qry.group_by(*groupby_exprs)
@ -477,12 +481,12 @@ class SqlaTable(Model, BaseDatasource):
if extras: if extras:
where = extras.get('where') where = extras.get('where')
if where: if where:
where_clause_and += [wrap_clause_in_parens( where = template_processor.process_template(where)
template_processor.process_template(where))] where_clause_and += [sa.text('({})'.format(where))]
having = extras.get('having') having = extras.get('having')
if having: if having:
having_clause_and += [wrap_clause_in_parens( having = template_processor.process_template(having)
template_processor.process_template(having))] having_clause_and += [sa.text('({})'.format(having))]
if granularity: if granularity:
qry = qry.where(and_(*([time_filter] + where_clause_and))) qry = qry.where(and_(*([time_filter] + where_clause_and)))
else: else:
@ -529,7 +533,7 @@ class SqlaTable(Model, BaseDatasource):
qry_start_dttm = datetime.now() qry_start_dttm = datetime.now()
engine = self.database.get_sqla_engine() engine = self.database.get_sqla_engine()
qry = self.get_sqla_query(**query_obj) qry = self.get_sqla_query(**query_obj)
sql = str(qry) sql = self.get_query_str(**query_obj)
status = QueryStatus.SUCCESS status = QueryStatus.SUCCESS
error_message = None error_message = None
df = None df = None
@ -537,6 +541,7 @@ class SqlaTable(Model, BaseDatasource):
df = pd.read_sql_query(qry, con=engine) df = pd.read_sql_query(qry, con=engine)
except Exception as e: except Exception as e:
status = QueryStatus.FAILED status = QueryStatus.FAILED
logging.exception(e)
error_message = str(e) error_message = str(e)
return QueryResult( return QueryResult(

View File

@ -415,14 +415,6 @@ class timeout(object):
logging.warning("timeout can't be used in the current context") logging.warning("timeout can't be used in the current context")
logging.exception(e) logging.exception(e)
def wrap_clause_in_parens(sql):
"""Wrap where/having clause with parenthesis if necessary"""
if sql.strip():
sql = '({})'.format(sql)
return sa.text(sql)
def pessimistic_connection_handling(target): def pessimistic_connection_handling(target):
@event.listens_for(target, "checkout") @event.listens_for(target, "checkout")
def ping_connection(dbapi_connection, connection_record, connection_proxy): def ping_connection(dbapi_connection, connection_record, connection_proxy):

View File

@ -1125,8 +1125,11 @@ class Superset(BaseSupersetView):
""" """
# TODO: Cache endpoint by user, datasource and column # TODO: Cache endpoint by user, datasource and column
datasource_class = ConnectorRegistry.sources[datasource_type] datasource_class = ConnectorRegistry.sources[datasource_type]
datasource = db.session.query( datasource = (
datasource_class).filter_by(id=datasource_id).first() db.session.query(datasource_class)
.filter_by(id=datasource_id)
.first()
)
if not datasource: if not datasource:
return json_error_response(DATASOURCE_MISSING_ERR) return json_error_response(DATASOURCE_MISSING_ERR)

View File

@ -25,8 +25,6 @@ from flask_babel import lazy_gettext as _
from markdown import markdown from markdown import markdown
import simplejson as json import simplejson as json
from six import string_types, PY3 from six import string_types, PY3
from werkzeug.datastructures import ImmutableMultiDict, MultiDict
from werkzeug.urls import Href
from dateutil import relativedelta as rdelta from dateutil import relativedelta as rdelta
from superset import app, utils, cache from superset import app, utils, cache