curl -X POST http://localhost:3000/api/schema/tree \
-H "Content-Type: application/json" \
-d '{
"host": "localhost",
"port": 5432,
"user": "postgres",
"password": "mypassword",
"database": "mydb",
"sslMode": "disable"
}'
[
{
"name": "mydb",
"schemas": [
{
"name": "public",
"tables": [
{
"name": "users",
"type": "table",
"schema": "public",
"rowCount": 1500
},
{
"name": "orders",
"type": "table",
"schema": "public",
"rowCount": 4200
},
{
"name": "user_summary",
"type": "view",
"schema": "public"
},
{
"name": "sales_stats",
"type": "materialized_view",
"schema": "public",
"rowCount": 120
}
]
},
{
"name": "analytics",
"tables": [
{
"name": "events",
"type": "table",
"schema": "analytics",
"rowCount": 98500
}
]
}
]
}
]
Retrieve database schema tree structure
curl -X POST http://localhost:3000/api/schema/tree \
-H "Content-Type: application/json" \
-d '{
"host": "localhost",
"port": 5432,
"user": "postgres",
"password": "mypassword",
"database": "mydb",
"sslMode": "disable"
}'
[
{
"name": "mydb",
"schemas": [
{
"name": "public",
"tables": [
{
"name": "users",
"type": "table",
"schema": "public",
"rowCount": 1500
},
{
"name": "orders",
"type": "table",
"schema": "public",
"rowCount": 4200
},
{
"name": "user_summary",
"type": "view",
"schema": "public"
},
{
"name": "sales_stats",
"type": "materialized_view",
"schema": "public",
"rowCount": 120
}
]
},
{
"name": "analytics",
"tables": [
{
"name": "events",
"type": "table",
"schema": "analytics",
"rowCount": 98500
}
]
}
]
}
]
pg_catalog, information_schema).
disable, require, prefer)public, myschema)table, view, or materialized_viewpg_class.reltuples (may be undefined for views)curl -X POST http://localhost:3000/api/schema/tree \
-H "Content-Type: application/json" \
-d '{
"host": "localhost",
"port": 5432,
"user": "postgres",
"password": "mypassword",
"database": "mydb",
"sslMode": "disable"
}'
[
{
"name": "mydb",
"schemas": [
{
"name": "public",
"tables": [
{
"name": "users",
"type": "table",
"schema": "public",
"rowCount": 1500
},
{
"name": "orders",
"type": "table",
"schema": "public",
"rowCount": 4200
},
{
"name": "user_summary",
"type": "view",
"schema": "public"
},
{
"name": "sales_stats",
"type": "materialized_view",
"schema": "public",
"rowCount": 120
}
]
},
{
"name": "analytics",
"tables": [
{
"name": "events",
"type": "table",
"schema": "analytics",
"rowCount": 98500
}
]
}
]
}
]
{
"error": "Missing required fields"
}
{
"error": "connection to server at \"localhost\" (127.0.0.1), port 5432 failed: Connection refused"
}
pg_catalog - PostgreSQL system cataloginformation_schema - SQL standard information schema/app/api/schema/tree/route.ts:4-6:
function isSystemSchema(name: string): boolean {
return name === 'pg_catalog' || name === 'information_schema'
}
pg_class.relkind to accurately determine object types:
| relkind | Type | Description |
|---|---|---|
r | table | Regular table |
v | view | View |
m | materialized_view | Materialized view |
p | table | Partitioned table |
/app/api/schema/tree/route.ts:74-82:
if (stat.relkind === 'v') mappedType = 'view'
else if (stat.relkind === 'm') mappedType = 'materialized_view'
else mappedType = 'table'
SELECT GREATEST(c.reltuples::bigint, 0) as row_estimate
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'public' AND c.relname = 'users'
ANALYZE. Run VACUUM ANALYZE for more accurate statistics.information_schema.schematainformation_schema.tablespg_class/app/api/schema/tree/route.ts:24-55:
// Fetch schemas
const schemasRes = await dbPool.query(poolConfig, `
SELECT schema_name
FROM information_schema.schemata
ORDER BY schema_name
`)
// Fetch tables and views metadata
const tablesRes = await dbPool.query(poolConfig, `
SELECT t.table_schema as schema,
t.table_name as name,
t.table_type as type
FROM information_schema.tables t
WHERE t.table_schema NOT IN ('pg_catalog','information_schema')
ORDER BY t.table_schema, t.table_name
`)
// Row count estimate and relkind
const statsRes = await dbPool.query(poolConfig, `
SELECT n.nspname as schema,
c.relname as name,
c.relkind,
GREATEST(c.reltuples::bigint, 0) as row_estimate
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname NOT IN ('pg_catalog','information_schema')
AND c.relkind IN ('r','v','m','p')
`)
/types/database.ts:1-9:
export interface DatabaseInfo {
name: string
schemas: SchemaInfo[]
}
export interface SchemaInfo {
name: string
tables: TableInfo[]
}
/types/database.ts:11-19:
export interface TableInfo {
name: string
type: "table" | "view" | "materialized_view"
schema: string
rowCount?: number
columnCount?: number
size?: string
createdAt?: Date
}