Skip to content

Commit 3fe5c2d

Browse files
committed
feat: add insert rows json function in redshift
1 parent 30d94b9 commit 3fe5c2d

2 files changed

Lines changed: 49 additions & 2 deletions

File tree

wavefront/server/packages/flo_cloud/flo_cloud/aws/redshift.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import os
2+
import json
23
import string
34
import logging
45
from typing import List, Dict, Any, Optional, Tuple
@@ -328,6 +329,52 @@ def execute_many(self, command: str, params_list: List[Dict[str, Any]]) -> int:
328329
logger.error(f'Batch execution error: {e}')
329330
raise
330331

332+
def insert_rows_json(self, table_name: str, data: List[Dict[str, Any]]) -> int:
333+
"""
334+
Insert rows provided as a list of dictionaries into a table.
335+
336+
Dict/list values are serialized to JSON strings so they can be stored
337+
in VARCHAR/SUPER columns. Columns are derived from the first row, so all
338+
rows are expected to share the same keys.
339+
340+
Args:
341+
table_name: Fully qualified target table name (e.g. 'db.schema.table')
342+
data: List of dictionaries, each representing a row
343+
344+
Returns:
345+
Number of rows inserted
346+
"""
347+
if not data:
348+
return 0
349+
350+
columns = list(data[0].keys())
351+
serialized = [
352+
{
353+
col: json.dumps(row.get(col))
354+
if isinstance(row.get(col), (dict, list))
355+
else row.get(col)
356+
for col in columns
357+
}
358+
for row in data
359+
]
360+
361+
column_list = ', '.join(f'"{col}"' for col in columns)
362+
placeholders = ', '.join(f':{col}' for col in columns)
363+
command = f'INSERT INTO {table_name} ({column_list}) VALUES ({placeholders})'
364+
365+
with self.get_connection() as connection:
366+
cursor = connection.cursor()
367+
try:
368+
cursor.executemany(command, serialized)
369+
connection.commit()
370+
return cursor.rowcount
371+
except RedshiftError as e:
372+
connection.rollback()
373+
logger.error(f'Insert error: {e}')
374+
raise
375+
finally:
376+
cursor.close()
377+
331378
def execute_transaction(
332379
self, commands: List[Tuple[str, Optional[Dict[str, Any]]]]
333380
) -> bool:

wavefront/server/plugins/datasource/datasource/redshift/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ def fetch_data(
6161
group_by=group_by,
6262
)
6363

64-
def insert_rows_json(self, table_name: str, data):
65-
pass
64+
def insert_rows_json(self, table_name: str, data: List[Dict[str, Any]]) -> None:
65+
self.client.insert_rows_json(f'{self.db_name}.{table_name}', data)
6666

6767
async def execute_query(
6868
self, query: str, use_legacy_sql: bool = False, dry_run: bool = False, **kwargs

0 commit comments

Comments
 (0)