CAPÍTULO 3 · Cada pieza encuentra su responsabilidad
Compartir conexiones sin confundirlas con las consultas
La revisión del ORM resolvió una parte del costo, pero SensorHub también necesita atender trabajo simultáneo. Abrir conexiones repetidamente añade esfuerzo, y permitir que cada proceso abra tantas como quiera puede presionar una base pequeña. El equipo necesita decidir cuánto acceso concurrente puede sostener, no solo cuánto tarda una consulta aislada.
La experiencia con psycopg 3 y su pool entra aquí como respuesta a esa necesidad. Las conexiones se prestan y se reutilizan dentro de límites definidos. Al dimensionarlos contamos procesos e instancias: el máximo de un pool no representa automáticamente el máximo de toda la aplicación. También reservamos espacio para tareas y administración.
El pool no reduce las consultas N+1 que acabamos de estudiar; complementa aquella mejora. Mantener ambas preguntas separadas nos ayuda a medir bien. Con el acceso a datos mejor organizado, podemos volver a observar la lógica del proyecto. Hay operaciones que ni siquiera deberían necesitar una conexión, como convertir una unidad o aplicar un cálculo puro.
Leer esta parte dentro del relato completo →DEL RELATO A LA PRÁCTICA
Vamos a desarrollar esta decisión con su mapa, explicación, código y ejercicio.
MIRA · CONECTA · COMPRENDE
Conexiones con un presupuesto
Las flechas resumen el recorrido conceptual. Los controles y dependencias se detallan debajo.
Selecciona una pieza para destacar su responsabilidad.
Leer la explicación del mapa
- Procesos. Cada worker usa su pool
- Pool. Presta conexiones con límite
- PostgreSQL. Recibe consultas y transacciones
- Medición. Observa espera y conexiones
01 / EL PROBLEMA
¿Para qué sirve?
Abrir conexiones repetidamente cuesta tiempo; abrir demasiadas puede saturar una base pequeña. El equipo necesita un presupuesto de conexiones para procesos web, tareas y administración.
02 / COMPRENDER
El concepto, explicado
El equipo utiliza psycopg 3 con los extras binary y pool. El código de referencia disponible ya incluye psycopg[binary,pool] y una función de configuración del pool; esta lección desarrolla el motivo y sus límites. binary facilita la instalación con paquetes precompilados; pool añade gestión de conexiones, no transforma las consultas.
En Django 5.2, OPTIONS.pool configura el pool de psycopg. Usa CONN_MAX_AGE=0: las conexiones persistentes de Django no se combinan con este pool. Mantener una conexión abierta por hilo y prestar conexiones desde un pool son estrategias distintas.
Cada proceso mantiene su propio pool. Dos instancias con tres workers y max_size=4 pueden reservar hasta 24 conexiones de runtime; hay que sumar tareas, migraciones, herramientas y margen. min_size tampoco es una cifra global. Un timeout limita cuánto espera una solicitud sin conexión disponible.
El pool no elimina N+1 ni vuelve rápida una consulta sin índice. Primero cuenta consultas y revisa planes; después mide conexiones activas, espera del pool, duración de transacciones y latencia. Mantén transacciones breves y no ocupes una conexión mientras esperas servicios externos.
Al migrar desde psycopg2, resuelve el entorno con psycopg 3, revisa imports directos y comportamiento de adaptadores, y prueba consultas, transacciones y migraciones. Los ejemplos no cambian automáticamente la academia pública, que sigue usando SQLite.
03 / CONSTRUIR
Implementación paso a paso
- Inventariar Django, driver y dependencias; preparar una migración probada a psycopg 3.
- Definir límite de conexiones por proceso y presupuesto total.
- Configurar pool, CONN_MAX_AGE=0 y TLS acorde con el servidor.
- Ensayar carga, agotamiento del pool, reintentos y cierre de transacciones.
- Medir N+1 por separado y ajustar el pool con evidencia.
04 / APLICAR
Ejemplo en SensorHub
# En un entorno de prueba del proyecto que usa PostgreSQL:
# python -m pip install "psycopg[binary,pool]"
# Fijar versiones verificadas en requirements.txt antes de publicar.
# Fragmento de production.py (Django 5.2; requiere variables y CA válidas):
import os
DATABASES = {"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": os.environ["DB_NAME"],
"USER": os.environ["DB_USER"],
"PASSWORD": os.environ["DB_PASSWORD"],
"HOST": os.environ["DB_HOST"],
"PORT": os.environ.get("DB_PORT", "5432"),
"CONN_MAX_AGE": 0,
"OPTIONS": {
"sslmode": "verify-full",
"sslrootcert": os.environ["DB_SSLROOTCERT"],
"pool": {"min_size": 1, "max_size": 4, "timeout": 5},
},
}}
# Valores de laboratorio: medir y ajustar, no copiar como capacidad universal.
# Presupuesto runtime: instancias * workers * max_size
# 2 * 3 * 4 = 24; sumar otros procesos y margen del servidor.Cómo leer el ejemplo
- El ORM continúa usando django.db.backends.postgresql.
- max_size es por proceso; escalar workers también escala conexiones.
- verify-full necesita hostname y cadena de confianza válidos.
Error habitual
Configurar 20 conexiones por worker sin multiplicar por procesos, o usar el pool como remedio para N+1.
05 / PRACTICAR
Tu turno
Hay 2 instancias, 4 workers y pools de máximo 5. ¿Cuántas conexiones debes presupuestar como máximo solo para web?
Ver solución orientativa
40 conexiones web. Añade tareas, migraciones, soporte y margen; reduce pools o workers si el servidor no dispone de ese presupuesto.
06 / VERIFICAR
Cómo sabes que funciona
- CONN_MAX_AGE es 0 al activar este pool.
- Las dependencias resueltas usan psycopg 3.
- La aplicación maneja espera y agotamiento del pool.
- Las consultas y conexiones se miden como problemas distintos.
Para profundizar
Documentación oficial para comprobar configuración, permisos y condiciones vigentes. Revisión del tema: 2026-10-12.
CONTINUAR LA EXPERIENCIA
El siguiente paso del recorrido:
UTIL_LIB: funciones puras y unidades →Continuar en modo relato