Commit
路
5c04851
1
Parent(s):
926fb90
mv2
Browse files
app.py
CHANGED
|
@@ -393,13 +393,46 @@ def execute_sql_query(query, db_connection):
|
|
| 393 |
if len(rows) == 1 and len(rows[0]) == 1:
|
| 394 |
return str(rows[0][0])
|
| 395 |
|
| 396 |
-
# Si hay m煤ltiples filas, formatear como tabla
|
| 397 |
try:
|
| 398 |
-
|
| 399 |
-
|
| 400 |
-
|
| 401 |
-
|
| 402 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 403 |
return "\n".join([str(row) for row in rows])
|
| 404 |
|
| 405 |
except Exception as e:
|
|
@@ -677,6 +710,31 @@ async def stream_agent_response(question: str, chat_history: List[List[str]]) ->
|
|
| 677 |
if chart_fig is not None:
|
| 678 |
logger.info("Chart generated from second-pass SQL execution (markdown parse).")
|
| 679 |
chart_state = {"data": data_list, "x_col": x_col, "y_col": y_col, "title": f"{y_col} por {x_col}", "chart_type": desired_type}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 680 |
else:
|
| 681 |
logger.info("No DB connection on second pass; skipping.")
|
| 682 |
except Exception as e:
|
|
|
|
| 393 |
if len(rows) == 1 and len(rows[0]) == 1:
|
| 394 |
return str(rows[0][0])
|
| 395 |
|
| 396 |
+
# Si hay m煤ltiples filas, formatear como tabla markdown robusta
|
| 397 |
try:
|
| 398 |
+
# Prefer row mapping if available
|
| 399 |
+
headers = []
|
| 400 |
+
try:
|
| 401 |
+
headers = list(rows[0]._mapping.keys()) # SQLAlchemy 2.x
|
| 402 |
+
except Exception:
|
| 403 |
+
try:
|
| 404 |
+
headers = list(result.keys()) # Fallback
|
| 405 |
+
except Exception:
|
| 406 |
+
# As last resort, numeric headers
|
| 407 |
+
headers = [str(i) for i in range(len(rows[0]))]
|
| 408 |
+
|
| 409 |
+
# Build markdown
|
| 410 |
+
lines = []
|
| 411 |
+
header_line = "| " + " | ".join(headers) + " |"
|
| 412 |
+
sep_line = "|" + "|".join([" --- " for _ in headers]) + "|"
|
| 413 |
+
lines.append(header_line)
|
| 414 |
+
lines.append(sep_line)
|
| 415 |
+
for r in rows:
|
| 416 |
+
try:
|
| 417 |
+
mapping = dict(getattr(r, "_mapping", {}))
|
| 418 |
+
except Exception:
|
| 419 |
+
mapping = {}
|
| 420 |
+
values = []
|
| 421 |
+
for h in headers:
|
| 422 |
+
if mapping:
|
| 423 |
+
v = mapping.get(h, "")
|
| 424 |
+
else:
|
| 425 |
+
# Tuple-style row
|
| 426 |
+
idx = headers.index(h)
|
| 427 |
+
try:
|
| 428 |
+
v = r[idx]
|
| 429 |
+
except Exception:
|
| 430 |
+
v = ""
|
| 431 |
+
values.append(str(v))
|
| 432 |
+
lines.append("| " + " | ".join(values) + " |")
|
| 433 |
+
return "\n".join(lines)
|
| 434 |
+
except Exception:
|
| 435 |
+
# Formato simple si algo falla
|
| 436 |
return "\n".join([str(row) for row in rows])
|
| 437 |
|
| 438 |
except Exception as e:
|
|
|
|
| 710 |
if chart_fig is not None:
|
| 711 |
logger.info("Chart generated from second-pass SQL execution (markdown parse).")
|
| 712 |
chart_state = {"data": data_list, "x_col": x_col, "y_col": y_col, "title": f"{y_col} por {x_col}", "chart_type": desired_type}
|
| 713 |
+
else:
|
| 714 |
+
# If no table, try parsing tuple-like rows shown as lines: ('LABEL', N)
|
| 715 |
+
tuple_lines = [l.strip() for l in str(query_result).split('\n') if l.strip()]
|
| 716 |
+
parsed = []
|
| 717 |
+
for l in tuple_lines:
|
| 718 |
+
m = re.match(r"^\(\'?\s*([^',]+?)\s*\'?,\s*(\d+(?:\.\d+)?)\)$", l)
|
| 719 |
+
if m:
|
| 720 |
+
label = m.group(1).strip()
|
| 721 |
+
try:
|
| 722 |
+
value = float(m.group(2))
|
| 723 |
+
except Exception:
|
| 724 |
+
continue
|
| 725 |
+
parsed.append({"label": label, "value": value})
|
| 726 |
+
if len(parsed) >= 2:
|
| 727 |
+
desired_type = 'pie' if any(k in q_lower for k in ["gr谩fico circular", "grafico circular", "pie", "pastel"]) else 'bar'
|
| 728 |
+
chart_fig = generate_chart(
|
| 729 |
+
data=parsed,
|
| 730 |
+
chart_type=desired_type,
|
| 731 |
+
x="label",
|
| 732 |
+
y="value",
|
| 733 |
+
title="Distribuci贸n"
|
| 734 |
+
)
|
| 735 |
+
if chart_fig is not None:
|
| 736 |
+
logger.info("Chart generated from tuple-like SQL output parse.")
|
| 737 |
+
chart_state = {"data": parsed, "x_col": "label", "y_col": "value", "title": "Distribuci贸n", "chart_type": desired_type}
|
| 738 |
else:
|
| 739 |
logger.info("No DB connection on second pass; skipping.")
|
| 740 |
except Exception as e:
|