python.db.missing_timeout
Stability
High
Detects database connections and queries that don’t have proper timeout configuration, which can lead to hanging connections and cascading failures.
Why It Matters
Section titled “Why It Matters”Database connections without timeouts can:
- Hang indefinitely — Network issues can cause connections to wait forever
- Exhaust connection pools — Stuck connections are never returned to the pool
- Cause cascading failures — Application workers get blocked waiting for DB
- Prevent graceful shutdown — Long-running queries ignore shutdown signals
Example
Section titled “Example”# ❌ Before (no timeout)from sqlalchemy import create_engine
engine = create_engine("postgresql://localhost/db")# ✅ After (with timeout)from sqlalchemy import create_engine
engine = create_engine( "postgresql://localhost/db", connect_args={"connect_timeout": 10}, pool_pre_ping=True, # Also recommended)What Unfault Detects
Section titled “What Unfault Detects”- SQLAlchemy
create_engine()withoutconnect_argstimeout - SQLAlchemy
create_async_engine()without timeout - psycopg2/psycopg
connect()withoutconnect_timeout - asyncpg
connect()withouttimeoutparameter
Auto-Fix
Section titled “Auto-Fix”Unfault generates patches that add appropriate timeout parameters:
# SQLAlchemy (sync)engine = create_engine( DATABASE_URL, connect_args={"connect_timeout": 10},)
# SQLAlchemy (async with asyncpg)engine = create_async_engine( DATABASE_URL, connect_args={"timeout": 10}, # asyncpg uses 'timeout')
# psycopg2conn = psycopg2.connect(dsn, connect_timeout=10)
# asyncpgconn = await asyncpg.connect(dsn, timeout=10)Best Practices
Section titled “Best Practices”# Comprehensive SQLAlchemy configurationengine = create_engine( DATABASE_URL, connect_args={ "connect_timeout": 10, "options": "-c statement_timeout=30000", # 30s query timeout }, pool_pre_ping=True, # Verify connections before use pool_recycle=3600, # Recycle connections hourly pool_timeout=30, # Max wait for connection from pool)