name: database-query-best-practices description: Prevent connection pool exhaustion when querying Railway PostgreSQL database. Use when (1) Running database queries from local environment, (2) Diagnosing "too many clients" errors, (3) Writing Python scripts that query production DB, (4) Checking connection pool status. CRITICAL - Always close connections immediately after use, use context managers, check pool status before queries.
CRITICAL SKILL - READ THIS BEFORE QUERYING RAILWAY DATABASE
When querying Railway production database from local development environment, you may encounter:
psycopg2.OperationalError: sorry, too many clients already
This happens when:
- Multiple local dev servers are running (npm run dev, npm run develop)
- Each dev server holds database connections open
- Connection pool limit is reached (300 total connections)
- No new connections can be established
Before ANY database query, check active connections:
python3 << 'EOF'
import psycopg2
DATABASE_URL = "postgresql://postgres:password@host:port/railway"
try:
conn = psycopg2.connect(DATABASE_URL, connect_timeout=10)
cur = conn.cursor()
# Check active connections
cur.execute("""
SELECT count(*)
FROM pg_stat_activity
WHERE datname = 'railway'
""")
active = cur.fetchone()[0]
# Check pool limit
cur.execute("SHOW max_connections")
max_conn = cur.fetchone()[0]
print(f"Active connections: {active}/{max_conn}")
if active > int(max_conn) * 0.9:
print(f"WARNING: Connection pool at {(active/int(max_conn))*100:.1f}% capacity")
print("Consider closing dev servers before querying")
else:
print("Connection pool healthy - safe to query")
cur.close()
conn.close()
except Exception as e:
print(f"Cannot connect: {e}")
print("\nSOLUTION:")
print("1. Kill local dev servers: pkill -9 -f 'npm run dev'")
print("2. Wait 30 seconds for connections to close")
print("3. Try again")
EOF
NEVER do this:
conn = psycopg2.connect(DATABASE_URL)
cur = conn.cursor()
cur.execute("SELECT * FROM users")
# Forgot to close! Connection leak!
ALWAYS do this:
import psycopg2
DATABASE_URL = "postgresql://..."
try:
conn = psycopg2.connect(DATABASE_URL, connect_timeout=30)
cur = conn.cursor()
# Do your queries
cur.execute("SELECT * FROM users")
results = cur.fetchall()
# Process results...
finally:
# ALWAYS close in finally block
if cur:
cur.close()
if conn:
conn.close()
For one-off queries, open connection, query, close immediately:
def get_user_count():
"""Get user count - connection opened and closed in function"""
conn = None
try:
conn = psycopg2.connect(DATABASE_URL, connect_timeout=30)
cur = conn.cursor()
cur.execute("SELECT COUNT(*) FROM users")
count = cur.fetchone()[0]
cur.close()
return count
finally:
if conn:
conn.close() # Connection immediately released
# Good: Connection closed after function returns
user_count = get_user_count()
If you need to run database queries, stop dev servers first:
# Stop all dev servers
pkill -9 -f "npm run dev"
pkill -9 -f "npm run develop"
# Wait for connections to close
sleep 10
# Now safe to query
python3 scripts/your_query_script.py
# Restart dev servers after
cd src/backend && npm run dev &
cd AINative-website && npm run dev &
Instead of Python scripts, use Railway CLI when possible:
# Login to Railway
railway login
# Link to project
railway link
# Run SQL query directly
railway run psql -c "SELECT COUNT(*) FROM users WHERE created_at >= NOW() - INTERVAL '30 days'"
This uses Railway's managed connections and doesn't consume local pool.
If you encounter "too many clients already":
pkill -9 -f "npm run dev"
pkill -9 -f "npm run develop"
pkill -9 node
sleep 30 # Wait for DB connections to close
railway run psql -c "
SELECT
pid,
usename,
application_name,
client_addr,
state,
query_start
FROM pg_stat_activity
WHERE datname = 'railway'
ORDER BY query_start DESC
LIMIT 20"
railway run psql -c "
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE datname = 'railway'
AND state = 'idle'
AND query_start < NOW() - INTERVAL '10 minutes'"
Before running ANY database query, verify:
小葱技能7w4.net有完整的技能分类。
The Golden Rule:
ALWAYS close database connections immediately after use. NEVER leave connections open in dev servers during queries.
Best Approach: 1. Stop dev servers 2. Query database 3. Close connection 4. Restart dev servers
Even Better: Use Railway CLI for ad-hoc queries instead of Python scripts.
这个 Skill 质量中等偏上。优点是问题定位准确,提供的解决方法和代码示例都很实用,预查询检查清单能有效帮助避免问题。不足是内容覆盖范围有限,只针对特定数据库环境,缺乏更全面的使用指南和改进建议。对于需要处理数据库连接管理的开发者来说有一定帮助,但实用性和泛用性还有提升空间。