Add custom JSON encoder for PostgreSQL (#3442)

To handle columns with [range types][1] and display them as a
string custom JSON encoder for PostgreSQL was added.

Merging this PR will fix issue #1764

[1]:https://www.postgresql.org/docs/9.3/rangetypes.html
This commit is contained in:
Sergei Beregov
2019-02-25 17:52:45 +02:00
committed by Arik Fraimovich
parent b56cc1cd16
commit 75c34bf18d

View File

@@ -3,9 +3,10 @@ import logging
import select
import psycopg2
from psycopg2.extras import Range
from redash.query_runner import *
from redash.utils import json_dumps, json_loads
from redash.utils import JSONEncoder, json_dumps, json_loads
logger = logging.getLogger(__name__)
@@ -28,6 +29,26 @@ types_map = {
}
class PostgreSQLJSONEncoder(JSONEncoder):
def default(self, 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 super(PostgreSQLJSONEncoder, self).default(o)
def _wait(conn, timeout=None):
while 1:
try:
@@ -165,7 +186,7 @@ class PostgreSQL(BaseSQLQueryRunner):
data = {'columns': columns, 'rows': rows}
error = None
json_data = json_dumps(data, ignore_nan=True)
json_data = json_dumps(data, ignore_nan=True, cls=PostgreSQLJSONEncoder)
else:
error = 'Query completed but it returned no data.'
json_data = None