Skip to content

Commit

Permalink
[bugfix] dealing with DBAPIs that return unserilizable types (apache#…
Browse files Browse the repository at this point in the history
…4200)

Funky datatypes in some databases like BLOBs will have the DBAPI return
python types that can't be serialized to JSON out of the box.

Currently, when this happens SQL Lab fails in a bad way with a gigantic
HTML error message.

This allows specifying a pessimistic JSON serializer handler that will
simply show "Unserializable [type]"
  • Loading branch information
mistercrunch authored and michellethomas committed May 23, 2018
1 parent 889b94f commit e9ef674
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 4 deletions.
16 changes: 13 additions & 3 deletions superset/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ def base_json_conv(obj):
return str(obj)


def json_iso_dttm_ser(obj):
def json_iso_dttm_ser(obj, pessimistic=False):
"""
json serializer that deals with dates
Expand All @@ -317,11 +317,21 @@ def json_iso_dttm_ser(obj):
elif isinstance(obj, time):
obj = obj.isoformat()
else:
raise TypeError(
'Unserializable object {} of type {}'.format(obj, type(obj)))
if pessimistic:
return 'Unserializable [{}]'.format(type(obj))
else:
raise TypeError(
'Unserializable object {} of type {}'.format(obj, type(obj)))
return obj


def pessimistic_json_iso_dttm_ser(obj):
"""Proxy to call json_iso_dttm_ser in a pessimistic way
If one of object is not serializable to json, it will still succeed"""
return json_iso_dttm_ser(obj, pessimistic=True)


def datetime_to_epoch(dttm):
if dttm.tzinfo:
epoch_with_tz = pytz.utc.localize(EPOCH)
Expand Down
4 changes: 3 additions & 1 deletion superset/views/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2316,12 +2316,14 @@ def sql_json(self):
data = sql_lab.get_sql_results(
query_id=query_id, return_results=True,
template_params=template_params)
payload = json.dumps(
data, default=utils.pessimistic_json_iso_dttm_ser)
except Exception as e:
logging.exception(e)
return json_error_response('{}'.format(e))
if data.get('status') == QueryStatus.FAILED:
return json_error_response(payload=data)
return json_success(json.dumps(data, default=utils.json_iso_dttm_ser))
return json_success(payload)

@has_access
@expose('/csv/<client_id>')
Expand Down

0 comments on commit e9ef674

Please sign in to comment.