En pocas palabras
Toolkit para definir contratos de datos y obtener acceso tipado y migraciones desde aplicaciones TypeScript.
Qué problema resuelve
Consultas y cambios de esquema con errores frecuentes y contratos desalineados con el código.
Cuándo utilizarlo
Backends Node.js y TypeScript. Ejemplo: consultar clientes y pedidos con tipos derivados del modelo.
De la idea a la práctica
Funcionamiento, ejemplos y decisiones para pasar al siguiente nivel.
En el Radar compartido: Trial (valoración de la edición aportada).
Cómo funciona
Los modelos se expresan en una definición de contrato o esquema Prisma. A partir de ella se obtiene acceso tipado y herramientas de migración; los resultados se usan como objetos en la aplicación.
Ejemplo de uso
Añadir un campo opcional al contrato, preparar la migración y actualizar consultas. Probar con una copia representativa y diseñar el despliegue para que versiones anterior y nueva convivan.
Esquema de ejemplo
model Cliente {
id String @id @default(uuid())
documento String @unique
nombre String
creditos Credito[]
createdAt DateTime @default(now())
}
model Credito {
id String @id @default(uuid())
cliente Cliente @relation(fields: [clienteId], references: [id])
clienteId String
monto Decimal @db.Decimal(14, 2)
estado Estado @default(PENDIENTE)
diasMora Int @default(0)
@@index([clienteId, estado])
}
enum Estado {
PENDIENTE
VIGENTE
CANCELADO
}
Consultas tipadas
const enMora = await prisma.credito.findMany({
where: { estado: 'VIGENTE', diasMora: { gt: 30 } },
select: {
id: true,
monto: true,
cliente: { select: { nombre: true, documento: true } },
},
orderBy: { diasMora: 'desc' },
take: 50,
});
// Transacción interactiva
await prisma.$transaction(async (tx) => {
const credito = await tx.credito.update({
where: { id },
data: { estado: 'CANCELADO' },
});
await tx.pago.create({ data: { creditoId: credito.id, monto: saldo } });
});
// SQL directo cuando hace falta (parámetros seguros por plantilla)
const filas =
await prisma.$queryRaw`SELECT estado, count(*) FROM "Credito" GROUP BY estado`;
Usa select para traer solo lo necesario. Las relaciones con include en bucles generan N+1 consultas: cárgalas en la consulta principal.
Flujo de migraciones
npx prisma migrate dev --name agregar_dias_mora # desarrollo: crea y aplica la migración
npx prisma migrate dev --create-only --name indice # generar SQL para editarlo antes de aplicar
npx prisma migrate deploy # CI/producción: aplica las pendientes
npx prisma db pull # introspección de una base existente
Revisa el SQL generado en el pull request. Para tablas grandes, edita la migración para usar operaciones sin bloqueo (como CREATE INDEX CONCURRENTLY en PostgreSQL), y aplica el patrón expand and contract para renombrados.
Producción
- Pool de conexiones: en serverless, limita conexiones por instancia (
connection_limit) o usa un pooler externo. - Logs de consultas (
log: ['query', 'warn', 'error']) en desarrollo para ver el SQL real. - Versiones mayores: las últimas versiones han cambiado la generación del cliente y la configuración (
prisma.config.ts); sigue la guía de actualización de la versión que uses.
Prisma frente a alternativas
Drizzle ORM ofrece un enfoque más cercano a SQL y sin paso de generación; Kysely es un query builder tipado; TypeORM y MikroORM siguen patrones clásicos de ORM. Prisma destaca por la experiencia de desarrollo y el esquema declarativo; a cambio, abstrae más el SQL.
Criterios de implementación
Inspeccionar SQL, índices y bloqueos; los tipos no garantizan consultas eficientes. Revisar soporte del motor y evitar copiar comandos de documentación de otra versión principal.
Continúa en las fuentes
Documentación oficial para verificar detalles y explorar más.