Try to fix multiline sql output splitting incorrectly

This commit is contained in:
Peter Stockings
2025-12-24 11:53:12 +11:00
parent 9c587a3a6c
commit eb36d8bf6b

13
app.py
View File

@@ -234,9 +234,10 @@ def run_sql_query(container_name: str, query: str) -> dict:
db_name = service_name.replace("-", "_") if service_name else None db_name = service_name.replace("-", "_") if service_name else None
if "postgres" in container_name: if "postgres" in container_name:
# Postgres: use psql with CSV-like output # Postgres: use psql with true CSV output (--csv requires psql 12+)
db_arg = ["-d", db_name] if db_name else [] db_arg = ["-d", db_name] if db_name else []
cmd = [DOCKER, "exec", container_name, "psql", "-U", "postgres"] + db_arg + ["-c", query, "-A", "-F", ","] # -A -F , is the older way, --csv is much better for multi-line/comma data
cmd = [DOCKER, "exec", container_name, "psql", "-U", "postgres", "-X", "--csv"] + db_arg + ["-c", query]
elif "mysql" in container_name or "mariadb" in container_name: elif "mysql" in container_name or "mariadb" in container_name:
# MySQL: use mysql with tab-separated output # MySQL: use mysql with tab-separated output
db_arg = [db_name] if db_name else [] db_arg = [db_name] if db_name else []
@@ -247,23 +248,21 @@ def run_sql_query(container_name: str, query: str) -> dict:
out = sh(cmd) out = sh(cmd)
# Parse output into rows and columns # Parse output into rows and columns
lines = out.splitlines() if not out.strip():
if not lines:
return {"columns": [], "rows": [], "message": "Query executed successfully (no results)"} return {"columns": [], "rows": [], "message": "Query executed successfully (no results)"}
if "postgres" in container_name: if "postgres" in container_name:
import csv import csv
from io import StringIO from io import StringIO
# Using StringIO on the full output allows csv.reader to handle multi-line fields
reader = csv.reader(StringIO(out)) reader = csv.reader(StringIO(out))
rows = list(reader) rows = list(reader)
if not rows: return {"columns": [], "rows": []} if not rows: return {"columns": [], "rows": []}
# psql -A can include a footer like "(1 row)", filter that out
if rows[-1] and rows[-1][0].startswith("(") and rows[-1][0].endswith(")"):
rows = rows[:-1]
columns = rows[0] columns = rows[0]
data = rows[1:] data = rows[1:]
else: else:
# MySQL is tab-separated by default with -B # MySQL is tab-separated by default with -B
lines = out.splitlines()
rows = [line.split("\t") for line in lines] rows = [line.split("\t") for line in lines]
columns = rows[0] columns = rows[0]
data = rows[1:] data = rows[1:]