From eb36d8bf6b9e4bf2c22dd8a7e26158fb67f3cc79 Mon Sep 17 00:00:00 2001 From: Peter Stockings Date: Wed, 24 Dec 2025 11:53:12 +1100 Subject: [PATCH] Try to fix multiline sql output splitting incorrectly --- app.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/app.py b/app.py index 09dc547..fa9e3b4 100644 --- a/app.py +++ b/app.py @@ -234,9 +234,10 @@ def run_sql_query(container_name: str, query: str) -> dict: db_name = service_name.replace("-", "_") if service_name else None 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 [] - 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: # MySQL: use mysql with tab-separated output 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) # Parse output into rows and columns - lines = out.splitlines() - if not lines: + if not out.strip(): return {"columns": [], "rows": [], "message": "Query executed successfully (no results)"} if "postgres" in container_name: import csv from io import StringIO + # Using StringIO on the full output allows csv.reader to handle multi-line fields reader = csv.reader(StringIO(out)) rows = list(reader) 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] data = rows[1:] else: # MySQL is tab-separated by default with -B + lines = out.splitlines() rows = [line.split("\t") for line in lines] columns = rows[0] data = rows[1:]