Saltar al contenido

Clase 26 - ORM - Prisma

#database #orm #prisma

🤔 ¿Qué es un ORM?

Un ORM (Object-Relational Mapping) es una técnica de programación que permite mapear objetos de un lenguaje de programación a tablas de una base de datos relacional. En esencia, actúa como una capa de abstracción entre tu código TypeScript y la base de datos.

🎯 ¿Para qué sirve un ORM?

  • Abstracción de SQL: Permite escribir consultas usando objetos y métodos en lugar de SQL puro, haciendo el código más legible y mantenible.
  • Type Safety: En TypeScript, los ORMs proporcionan tipado estático, evitando errores en tiempo de compilación y mejorando la experiencia de desarrollo.
  • Productividad: Reduce el boilerplate code necesario para operaciones CRUD básicas.
  • Portabilidad: Facilita el cambio entre diferentes sistemas de bases de datos sin reescribir las consultas.
  • Prevención de vulnerabilidades: Ayuda a prevenir inyecciones SQL mediante consultas parametrizadas automáticas.

🚀 ORMs populares en TypeScript

1. TypeORM

import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column()
email: string;
}
// Uso
const user = new User();
user.name = "Juan";
user.email = "juan@example.com";
await userRepository.save(user);

2. Prisma

// Schema definido en prisma/schema.prisma
model User {
id Int @id @default(autoincrement())
name String
email String @unique
}
// Uso en TypeScript
const user = await prisma.user.create({
data: {
name: "Juan",
email: "juan@example.com"
}
});

3. Sequelize

import { DataTypes, Model } from 'sequelize';
interface UserAttributes {
id: number;
name: string;
email: string;
}
class User extends Model<UserAttributes> implements UserAttributes {
public id!: number;
public name!: string;
public email!: string;
}
User.init({
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
name: { type: DataTypes.STRING, allowNull: false },
email: { type: DataTypes.STRING, allowNull: false, unique: true }
}, { sequelize });

🧠 ¿Qué es Prisma ORM?

Prisma es un ORM moderno para Node.js y TypeScript que facilita el trabajo con bases de datos relacionales. Permite interactuar con la base de datos usando código TypeScript, evitando la necesidad de escribir consultas SQL manualmente.

✅ Características Clave

  • TypeScript-first: Tipado estático, autocompletado e inferencia automática.

  • ⚙️ Schema centralizado: El modelo de datos se define en un único archivo .prisma.

  • 🔗 Soporte de relaciones entre tablas muy intuitivo.

  • 📦 Prisma Client: Cliente auto-generado y altamente tipado.

  • 🔄 Migraciones: Control de versiones del esquema de la base de datos.

  • 🧪 Compatibilidad con pruebas y desarrollo local.


🔧 Bases de Datos Compatibles

Prisma es compatible con las siguientes bases de datos relacionales:

  • PostgreSQL

  • MySQL

  • SQLite

  • SQL Server

  • CockroachDB

  • MongoDB (soporte con funciones limitadas)


📦 Instalación y Setup Básico

Paso 1: Inicializar un proyecto

Ventana de terminal
pnpm init -y
pnpm add -D prisma
pnpm prisma init

Esto crea:

  • Un archivo schema.prisma

  • Un directorio prisma/

  • Un archivo .env con la URL de conexión

Paso 2: Instalar Prisma Client

Ventana de terminal
pnpm add @prisma/client

📄 Prisma Schema: Estructura de schema.prisma

schema.prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
name String
email String @unique
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
author User @relation(fields: [authorId], references: [id])
authorId Int
}

🔍 Componentes del Schema

ComponenteDescripción
generatorDefine cómo se genera el cliente de Prisma
datasourceDefine la base de datos y la URL de conexión
modelDefine una tabla y sus campos
@idClave primaria
@default(autoincrement())Autoincremento de ID
@uniqueRestricción de unicidad
@relationDefine relaciones entre tablas

🔌 Prisma Client: El Puente con la Base de Datos

Prisma Client es una API auto-generada que permite consultar y modificar la base de datos desde tu código.

Ejemplo:

import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
// Crear usuario
const newUser = await prisma.user.create({
data: {
name: 'Juan',
email: 'juan@example.com',
},
})
// Consultar usuarios
const users = await prisma.user.findMany()

Tipos de Operaciones

  • create, createMany

  • findMany, findUnique, findFirst

  • update, updateMany

  • delete, deleteMany

  • upsert

  • aggregate, groupBy


🔄 Relaciones Entre Tablas

🔗 1:1

model User {
id Int @id @default(autoincrement())
profile Profile?
}
model Profile {
id Int @id @default(autoincrement())
bio String
user User @relation(fields: [userId], references: [id])
userId Int @unique
}

🔗 1:N

model User {
id Int @id @default(autoincrement())
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
author User @relation(fields: [authorId], references: [id])
authorId Int
}

🔗 N:M (Relación Muchos a Muchos)

model Student {
id Int @id @default(autoincrement())
name String
courses Course[] @relation("StudentCourses")
}
model Course {
id Int @id @default(autoincrement())
title String
students Student[] @relation("StudentCourses")
}
model Student {
id Int @id @default(autoincrement())
name String
courses StudentCourse[]
}
model Course {
id Int @id @default(autoincrement())
title String
students StudentCourse[]
}
model StudentCourse {
student Student @relation(fields: [studentId], references: [id])
studentId Int @map("student_id")
course Course @relation(fields: [courseId], references: [id])
courseId Int @map("course_id")
@@id([studentId, courseId])
@@map("student_course")
}

🚦 Migraciones

Prisma permite manejar cambios en la base de datos a través de migraciones:

Ventana de terminal
pnpm prisma migrate dev --name init

Esto:

  • Genera el SQL necesario

  • Aplica cambios

  • Actualiza el cliente de Prisma


🧪 Prisma Studio

Interfaz visual para ver y editar datos en tu DB:

Ventana de terminal
pnpm prisma studio

📂 Estructura Recomendada del Proyecto

  • Directorioproject/
    • Directorioprisma/
      • schema.prisma
      • Directoriomigrations/
    • Directoriosrc/
      • index.ts
    • package.json
    • .env

🎯 Ejercicio Práctico

Crear un sistema de gestión de biblioteca

  1. Modelar entidades:

    • Libro (Book): id, titulo, autor, publicado, disponible

    • Usuario (User): id, nombre, email

    • Préstamo (Loan): id, user, book, fechaPrestamo, fechaDevolucion

  2. Definir relaciones:

    • Un User puede tener muchos Loan

    • Un Book puede tener muchos Loan

  3. Usar Prisma Client para:

    • Registrar un nuevo préstamo

    • Consultar libros disponibles

    • Mostrar historial de préstamos por usuario


📚 Documentación Oficial