feat: enrich SQL explorer schema browser with PK/FK, row counts, search, collapsible tables

This commit is contained in:
Celes Renata
2026-04-17 06:22:04 +00:00
parent bbf7a6ee7b
commit cbe3fbe8b4
3 changed files with 149 additions and 26 deletions
+54 -6
View File
@@ -2121,24 +2121,72 @@ async def analytics_schema():
@app.get("/api/analytics/pg-schema")
async def pg_schema():
"""Return PostgreSQL table/column metadata for the schema browser."""
rows = await pool.fetch("""
SELECT t.table_name, c.column_name, c.data_type, c.is_nullable
# Columns with ordinal position
col_rows = await pool.fetch("""
SELECT t.table_name, c.column_name, c.data_type, c.is_nullable,
c.column_default
FROM information_schema.tables t
JOIN information_schema.columns c
ON t.table_name = c.table_name AND t.table_schema = c.table_schema
WHERE t.table_schema = 'public' AND t.table_type = 'BASE TABLE'
ORDER BY t.table_name, c.ordinal_position
""")
# Primary key columns
pk_rows = await pool.fetch("""
SELECT kcu.table_name, kcu.column_name
FROM information_schema.table_constraints tc
JOIN information_schema.key_column_usage kcu
ON tc.constraint_name = kcu.constraint_name
AND tc.table_schema = kcu.table_schema
WHERE tc.table_schema = 'public' AND tc.constraint_type = 'PRIMARY KEY'
""")
pk_set: set[tuple[str, str]] = {(r["table_name"], r["column_name"]) for r in pk_rows}
# Foreign key columns with referenced table
fk_rows = await pool.fetch("""
SELECT kcu.table_name, kcu.column_name,
ccu.table_name AS foreign_table
FROM information_schema.table_constraints tc
JOIN information_schema.key_column_usage kcu
ON tc.constraint_name = kcu.constraint_name
AND tc.table_schema = kcu.table_schema
JOIN information_schema.constraint_column_usage ccu
ON tc.constraint_name = ccu.constraint_name
AND tc.table_schema = ccu.table_schema
WHERE tc.table_schema = 'public' AND tc.constraint_type = 'FOREIGN KEY'
""")
fk_map: dict[tuple[str, str], str] = {
(r["table_name"], r["column_name"]): r["foreign_table"] for r in fk_rows
}
# Approximate row counts from pg_stat
count_rows = await pool.fetch("""
SELECT relname AS table_name, reltuples::bigint AS row_estimate
FROM pg_class
WHERE relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'public')
AND relkind = 'r'
""")
row_counts: dict[str, int] = {r["table_name"]: max(0, r["row_estimate"]) for r in count_rows}
tables: dict[str, dict[str, Any]] = {}
for row in rows:
for row in col_rows:
tname = row["table_name"]
if tname not in tables:
tables[tname] = {"name": tname, "columns": []}
tables[tname]["columns"].append({
tables[tname] = {"name": tname, "row_estimate": row_counts.get(tname, 0), "columns": []}
col_info: dict[str, Any] = {
"name": row["column_name"],
"type": row["data_type"],
"nullable": row["is_nullable"] == "YES",
})
}
if (tname, row["column_name"]) in pk_set:
col_info["primary_key"] = True
fk_ref = fk_map.get((tname, row["column_name"]))
if fk_ref:
col_info["references"] = fk_ref
if row["column_default"] is not None:
col_info["has_default"] = True
tables[tname]["columns"].append(col_info)
return {"catalog": "postgresql", "schema": "public", "tables": list(tables.values())}