Skip to content

Commit f0a390b

Browse files
aniket-s-kulkarniJesse
andauthored
New Query Runner: Netezza Performance Server (#5771)
Co-authored-by: Jesse <[email protected]>
1 parent 3624f8f commit f0a390b

File tree

5 files changed

+169
-1
lines changed

5 files changed

+169
-1
lines changed
1.25 KB
Loading

redash/query_runner/nz.py

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
from dataclasses import dataclass
2+
import logging
3+
import traceback
4+
import json
5+
6+
from redash.query_runner import *
7+
from redash.utils import json_dumps, json_loads
8+
9+
logger = logging.getLogger(__name__)
10+
11+
try:
12+
import nzpy
13+
import nzpy.core
14+
_enabled = True
15+
_nztypes = {
16+
nzpy.core.NzTypeInt1 : TYPE_INTEGER,
17+
nzpy.core.NzTypeInt2 : TYPE_INTEGER,
18+
nzpy.core.NzTypeInt : TYPE_INTEGER,
19+
nzpy.core.NzTypeInt8 : TYPE_INTEGER,
20+
nzpy.core.NzTypeBool : TYPE_BOOLEAN,
21+
nzpy.core.NzTypeDate : TYPE_DATE,
22+
nzpy.core.NzTypeTimestamp : TYPE_DATETIME,
23+
nzpy.core.NzTypeDouble : TYPE_FLOAT,
24+
nzpy.core.NzTypeFloat : TYPE_FLOAT,
25+
nzpy.core.NzTypeChar : TYPE_STRING,
26+
nzpy.core.NzTypeNChar : TYPE_STRING,
27+
nzpy.core.NzTypeNVarChar : TYPE_STRING,
28+
nzpy.core.NzTypeVarChar : TYPE_STRING,
29+
nzpy.core.NzTypeVarFixedChar : TYPE_STRING,
30+
nzpy.core.NzTypeNumeric : TYPE_FLOAT,
31+
}
32+
33+
_cat_types = {
34+
16: TYPE_BOOLEAN, # boolean
35+
17: TYPE_STRING, # bytea
36+
19: TYPE_STRING, # name type
37+
20: TYPE_INTEGER, # int8
38+
21: TYPE_INTEGER, # int2
39+
23: TYPE_INTEGER, # int4
40+
25: TYPE_STRING, # TEXT type
41+
26: TYPE_INTEGER, # oid
42+
28: TYPE_INTEGER, # xid
43+
700: TYPE_FLOAT, # float4
44+
701: TYPE_FLOAT, # float8
45+
705: TYPE_STRING, # unknown
46+
829: TYPE_STRING, # MACADDR type
47+
1042: TYPE_STRING, # CHAR type
48+
1043: TYPE_STRING, # VARCHAR type
49+
1082: TYPE_DATE, # date
50+
1083: TYPE_DATETIME,
51+
1114: TYPE_DATETIME, # timestamp w/ tz
52+
1184: TYPE_DATETIME,
53+
1700: TYPE_FLOAT, # NUMERIC
54+
2275: TYPE_STRING, # cstring
55+
2950: TYPE_STRING # uuid
56+
}
57+
except:
58+
_enabled = False
59+
_nztypes = {}
60+
_cat_types = {}
61+
62+
class Netezza(BaseSQLQueryRunner):
63+
noop_query = "SELECT 1"
64+
65+
@classmethod
66+
def configuration_schema(cls):
67+
return {
68+
"type": "object",
69+
"properties": {
70+
"user": {"type": "string"},
71+
"password": {"type": "string"},
72+
"host": {"type": "string", "default": "127.0.0.1"},
73+
"port": {"type": "number", "default": 5480},
74+
"database": {"type": "string", "title": "Database Name", "default":"system"},
75+
},
76+
"order": ["host", "port", "user", "password", "database"],
77+
"required": ["user", "password", "database"],
78+
"secret": ["password"],
79+
}
80+
81+
@classmethod
82+
def type(cls):
83+
return "nz"
84+
85+
def __init__(self, configuration):
86+
super().__init__(configuration)
87+
self._conn = None
88+
89+
@property
90+
def connection(self):
91+
if self._conn is None:
92+
self._conn = nzpy.connect(
93+
host = self.configuration.get("host"),
94+
user = self.configuration.get("user"),
95+
password = self.configuration.get("password"),
96+
port = self.configuration.get("port"),
97+
database = self.configuration.get("database")
98+
)
99+
return self._conn
100+
101+
def get_schema(self, get_stats=False):
102+
qry = '''
103+
select
104+
table_schema || '.' || table_name as table_name,
105+
column_name,
106+
data_type
107+
from
108+
columns
109+
where
110+
table_schema not in (^information_schema^, ^definition_schema^) and
111+
table_catalog = current_catalog;
112+
'''
113+
schema = {}
114+
with self.connection.cursor() as cursor:
115+
cursor.execute(qry)
116+
for table_name, column_name, data_type in cursor:
117+
if table_name not in schema:
118+
schema[table_name] = {"name": table_name, "columns": []}
119+
schema[table_name]["columns"].append({"name": column_name, "type": data_type})
120+
return list(schema.values())
121+
122+
@classmethod
123+
def enabled(cls):
124+
global _enabled
125+
return _enabled
126+
127+
def type_map(self, typid, func):
128+
global _nztypes, _cat_types
129+
typ = _nztypes.get(typid)
130+
if typ is None:
131+
return _cat_types.get(typid)
132+
# check for conflicts
133+
if typid == nzpy.core.NzTypeVarChar:
134+
return TYPE_BOOLEAN if 'bool' in func.__name__ else typ
135+
136+
if typid == nzpy.core.NzTypeInt2:
137+
return TYPE_STRING if 'text' in func.__name__ else typ
138+
139+
if typid in (nzpy.core.NzTypeVarFixedChar, nzpy.core.NzTypeVarBinary,
140+
nzpy.core.NzTypeNVarChar):
141+
return TYPE_INTEGER if 'int' in func.__name__ else typ
142+
return typ
143+
144+
def run_query(self, query, user):
145+
json_data, error = None, None
146+
try:
147+
with self.connection.cursor() as cursor:
148+
cursor.execute(query)
149+
if cursor.description is None:
150+
columns = {"columns":[], "rows":[]}
151+
else:
152+
columns = self.fetch_columns(
153+
[(val[0], self.type_map(val[1], cursor.ps['row_desc'][i]['func']))
154+
for i, val in enumerate(cursor.description)])
155+
rows = [
156+
dict(zip((column["name"] for column in columns), row))
157+
for row in cursor
158+
]
159+
160+
json_data = json.dumps({"columns": columns, "rows": rows})
161+
except:
162+
error = traceback.format_exc()
163+
return json_data, error
164+
165+
register(Netezza)

redash/settings/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@ def email_server_is_configured():
388388
"redash.query_runner.excel",
389389
"redash.query_runner.csv",
390390
"redash.query_runner.firebolt",
391+
"redash.query_runner.nz",
391392
"redash.query_runner.arango"
392393
]
393394

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,4 @@ werkzeug==0.16.1
6666
# It is not included by default because of the GPL license conflict.
6767
# ldap3==2.2.4
6868
Authlib==0.15.5
69-
advocate==1.0.0
69+
advocate==1.0.0

requirements_all_ds.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,6 @@ xlrd==2.0.1
4242
openpyxl==3.0.7
4343
firebolt-sdk
4444
pandas==1.3.4
45+
nzpy>=1.15
46+
nzalchemy
4547
python-arango==6.1.0

0 commit comments

Comments
 (0)