Alejandría

Busca en Alejandría

Lenguajes y marcos

Prisma ORM

Toolkit para definir contratos de datos y obtener acceso tipado y migraciones desde aplicaciones TypeScript.

01

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.

02

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.