diff --git a/redash/query_runner/cass.py b/redash/query_runner/cass.py index 1a56b99374..fb5ce3ee5d 100644 --- a/redash/query_runner/cass.py +++ b/redash/query_runner/cass.py @@ -26,12 +26,6 @@ def generate_ssl_options_dict(protocol, cert_path=None): return ssl_options -def custom_json_encoder(dec, o): - if isinstance(o, sortedset): - return list(o) - return None - - class Cassandra(BaseQueryRunner): noop_query = "SELECT dateof(now()) FROM system.local" @@ -39,6 +33,12 @@ class Cassandra(BaseQueryRunner): def enabled(cls): return enabled + @classmethod + def custom_json_encoder(cls, dec, o): + if isinstance(o, sortedset): + return list(o) + return None + @classmethod def configuration_schema(cls): return { diff --git a/redash/query_runner/mongodb.py b/redash/query_runner/mongodb.py index e22d76ca00..b775edb4f8 100644 --- a/redash/query_runner/mongodb.py +++ b/redash/query_runner/mongodb.py @@ -42,16 +42,6 @@ } -def custom_json_encoder(dec, o): - if isinstance(o, ObjectId): - return str(o) - elif isinstance(o, Timestamp): - return dec.default(o.as_datetime()) - elif isinstance(o, Decimal128): - return o.to_decimal() - return None - - date_regex = re.compile(r'ISODate\("(.*)"\)', re.IGNORECASE) @@ -170,6 +160,16 @@ def __init__(self, configuration): True if "replicaSetName" in self.configuration and self.configuration["replicaSetName"] else False ) + @classmethod + def custom_json_encoder(cls, dec, o): + if isinstance(o, ObjectId): + return str(o) + elif isinstance(o, Timestamp): + return dec.default(o.as_datetime()) + elif isinstance(o, Decimal128): + return o.to_decimal() + return None + def _get_db(self): kwargs = {} if self.is_replica_set: diff --git a/redash/query_runner/pg.py b/redash/query_runner/pg.py index 6b9422a74c..dc74aff2cc 100644 --- a/redash/query_runner/pg.py +++ b/redash/query_runner/pg.py @@ -55,18 +55,6 @@ } -def custom_json_encoder(dec, o): - if isinstance(o, Range): - # From: https://github.com/psycopg/psycopg2/pull/779 - if o._bounds is None: - return "" - - items = [o._bounds[0], str(o._lower), ", ", str(o._upper), o._bounds[1]] - - return "".join(items) - return None - - def _wait(conn, timeout=None): while 1: try: @@ -195,6 +183,18 @@ def configuration_schema(cls): def type(cls): return "pg" + @classmethod + def custom_json_encoder(cls, dec, o): + if isinstance(o, Range): + # From: https://github.com/psycopg/psycopg2/pull/779 + if o._bounds is None: + return "" + + items = [o._bounds[0], str(o._lower), ", ", str(o._upper), o._bounds[1]] + + return "".join(items) + return None + def _get_definitions(self, schema, query): results, error = self.run_query(query, None) diff --git a/redash/utils/__init__.py b/redash/utils/__init__.py index f03767606c..a4005b6725 100644 --- a/redash/utils/__init__.py +++ b/redash/utils/__init__.py @@ -74,7 +74,9 @@ class JSONEncoder(json.JSONEncoder): """Adapter for `json.dumps`.""" def __init__(self, **kwargs): - self.encoders = [m.custom_json_encoder for m in sys.modules.values() if hasattr(m, "custom_json_encoder")] + from redash.query_runner import query_runners + + self.encoders = [r.custom_json_encoder for r in query_runners.values() if hasattr(r, "custom_json_encoder")] super().__init__(**kwargs) def default(self, o):