Skip to content

Commit 8ed8abc

Browse files
authored
Update main.py
1 parent e6a3be7 commit 8ed8abc

File tree

1 file changed

+26
-17
lines changed

1 file changed

+26
-17
lines changed

main.py

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,23 @@ def verify(username, password):
2323
conn = duckdb.connect(path)
2424
return True
2525

26+
def convert_to_ndjson(result):
27+
columns = result.description
28+
data = result.fetchall()
29+
30+
ndjson_lines = []
31+
for row in data:
32+
row_dict = {columns[i][0]: row[i] for i in range(len(columns))}
33+
ndjson_lines.append(json.dumps(row_dict))
34+
35+
return '\n'.join(ndjson_lines).encode()
36+
2637
def convert_to_clickhouse_jsoncompact(result, query_time):
2738
columns = result.description
2839
data = result.fetchall()
29-
40+
3041
meta = [{"name": col[0], "type": col[1]} for col in columns]
31-
42+
3243
json_result = {
3344
"meta": meta,
3445
"data": data,
@@ -40,29 +51,28 @@ def convert_to_clickhouse_jsoncompact(result, query_time):
4051
"bytes_read": sum(len(str(item)) for row in data for item in row)
4152
}
4253
}
43-
54+
4455
return json.dumps(json_result)
4556

4657
def duckdb_query_with_errmsg(query, format):
4758
try:
4859
start_time = time.time()
4960
result = conn.execute(query)
5061
query_time = time.time() - start_time
51-
62+
5263
if format.lower() == 'jsoncompact':
5364
output = convert_to_clickhouse_jsoncompact(result, query_time)
5465
elif format.lower() == 'jsoneachrow':
55-
rows = result.fetchall()
56-
output = '\n'.join(json.dumps(row) for row in rows).encode()
66+
output = convert_to_ndjson(result)
5767
elif format.lower() == 'tsv':
5868
output = result.df().to_csv(sep='\t', index=False)
5969
else:
6070
output = result.fetchall()
61-
71+
6272
# Ensure output is in bytes before returning
6373
if isinstance(output, list):
6474
output = json.dumps(output).encode() # Convert list to JSON string and then encode
65-
75+
6676
return output, b""
6777
except Exception as e:
6878
return b"", str(e).encode()
@@ -92,13 +102,13 @@ def clickhouse():
92102
response = app.response_class(status=200)
93103
response.headers['Content-Type'] = 'application/json'
94104
response.headers['Accept-Ranges'] = 'bytes' # Indicate that range requests are supported
95-
105+
96106
# Set Content-Length for HEAD request
97107
content_length = len(result) if isinstance(result, bytes) else len(result.decode())
98108
response.headers['Content-Length'] = content_length
99-
109+
100110
return response
101-
111+
102112
return result, 200
103113

104114
# Log any warnings or errors
@@ -116,20 +126,20 @@ def play():
116126
body = request.get_data() or None
117127
format = request.args.get('default_format', default="JSONCompact", type=str)
118128
database = request.args.get('database', default="", type=str)
119-
129+
120130
if query is None:
121131
query = ""
122-
132+
123133
if body is not None:
124134
data = " ".join(body.decode('utf-8').strip().splitlines())
125135
query = f"{query} {data}"
126-
136+
127137
if not query:
128138
return "Error: no query parameter provided", 400
129-
139+
130140
if database:
131141
query = f"ATTACH '{database}' AS db; USE db; {query}"
132-
142+
133143
result, errmsg = duckdb_query_with_errmsg(query.strip(), format)
134144
if len(errmsg) == 0:
135145
return result, 200
@@ -156,4 +166,3 @@ def handle_404(e):
156166

157167
if __name__ == '__main__':
158168
app.run(host=host, port=port)
159-

0 commit comments

Comments
 (0)