Prisma ORM v6
Versión estable lanzada en diciembre de 2024. Introduce Driver Adapters estables, el archivo prisma.config.ts y el Query Compiler en preview.
Instalación
Requisitos previos:
- Node.js 18.x o superior (recomendado 20+)
- TypeScript 4.7+ (recomendado 5.x)
- Un proyecto Node.js inicializado (
npm init -y)
Instalación de dependencias
npm install @prisma/client@6
npm install -D prisma@6
Inicializar Prisma en el proyecto
npx prisma init
Este comando crea la siguiente estructura:
├── prisma/
│ └── schema.prisma ← Esquema de base de datos
├── .env ← Variables de entorno (DATABASE_URL)
Configuración de la base de datos
Variables de entorno
En el archivo .env generado, se define la URL de conexión:
# PostgreSQL
DATABASE_URL="postgresql://usuario:contraseña@localhost:5432/mi_base_de_datos"
# MySQL
DATABASE_URL="mysql://usuario:contraseña@localhost:3306/mi_base_de_datos"
# SQLite (ideal para desarrollo local)
DATABASE_URL="file:./dev.db"
Configuración del datasource en schema.prisma
datasource db {
provider = "postgresql" // "mysql" | "sqlite" | "sqlserver" | "cockroachdb"
url = env("DATABASE_URL")
}
Archivo prisma.config.ts
En v6 se introduce la posibilidad de usar un archivo de configuración TypeScript centralizado. En v7 será obligatorio, pero en v6 es opcional:
import { defineConfig } from "prisma/config";
import "dotenv/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
seed: "tsx prisma/seed.ts",
},
});
Creación de modelos
Los modelos en Prisma representan las tablas de la base de datos. Se definen en schema.prisma.
Sintaxis básica de un modelo
model Usuario {
id Int @id @default(autoincrement())
email String @unique
nombre String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
Tipos de datos más comunes
| Tipo Prisma | Equivalente SQL |
|---|---|
String | VARCHAR / TEXT |
Int | INTEGER |
Float | FLOAT / DOUBLE |
Boolean | BOOLEAN |
DateTime | TIMESTAMP |
Json | JSON / JSONB |
Bytes | BYTEA / BLOB |
Atributos de campo
@id // Clave primaria
@default(autoincrement()) // Valor por defecto
@default(now()) // Fecha actual
@unique // Restricción de unicidad
@updatedAt // Actualización automática al modificar
@map("nombre_columna") // Mapear a nombre distinto en BD
Relaciones entre modelos
Relación 1-N:
model Usuario {
id Int @id @default(autoincrement())
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
titulo String
autorId Int
autor Usuario @relation(fields: [autorId], references: [id])
}
Relación N-M:
model Post {
id Int @id @default(autoincrement())
categorias Categoria[]
}
model Categoria {
id Int @id @default(autoincrement())
posts Post[]
}
Relación 1-1:
model Usuario {
id Int @id @default(autoincrement())
perfil Perfil?
}
model Perfil {
id Int @id @default(autoincrement())
bio String
usuarioId Int @unique
usuario Usuario @relation(fields: [usuarioId], references: [id])
}
Migraciones
Crear y aplicar una migración
npx prisma migrate dev --name nombre_migracion
Este comando:
- Detecta los cambios en el esquema.
- Genera un archivo SQL en
prisma/migrations/. - Aplica la migración a la base de datos.
- Regenera el Prisma Client.
Otros comandos de migración útiles
# Aplicar migraciones en producción (sin generar nuevas)
npx prisma migrate deploy
# Resetear la base de datos y volver a aplicar todas las migraciones
npx prisma migrate reset
# Inspeccionar el estado de las migraciones
npx prisma migrate status
# Sincronizar el esquema directamente (sin generar migración, útil en dev)
npx prisma db push
Prisma Client — Configuración y uso
Generar el cliente
npx prisma generate
En v6, el cliente se genera en node_modules/@prisma/client por defecto (esto cambia en v7).
Instanciar el cliente
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
Buena práctica: instancia global en desarrollo
Para evitar múltiples instancias en entornos con hot reload (como Next.js):
// lib/prisma.ts
import { PrismaClient } from "@prisma/client";
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient };
export const prisma =
globalForPrisma.prisma ?? new PrismaClient({ log: ["query"] });
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
Operaciones básicas (CRUD)
Crear registros
Crear un único registro:
const nuevoUsuario = await prisma.usuario.create({
data: {
email: "ana@ejemplo.com",
nombre: "Ana García",
},
});
Crear múltiples registros a la vez:
await prisma.usuario.createMany({
data: [
{ email: "carlos@ejemplo.com", nombre: "Carlos López" },
{ email: "marta@ejemplo.com", nombre: "Marta Ruiz" },
],
skipDuplicates: true, // Ignora duplicados en lugar de lanzar error
});
Leer registros
Buscar por ID (findUnique):
const usuario = await prisma.usuario.findUnique({
where: { id: 1 },
});
Buscar el primero que coincida (findFirst):
const usuario = await prisma.usuario.findFirst({
where: { nombre: { contains: "Ana" } },
});
Obtener todos los registros (findMany):
const usuarios = await prisma.usuario.findMany();
Con filtros, orden y paginación:
const usuarios = await prisma.usuario.findMany({
where: {
nombre: { startsWith: "A" },
},
orderBy: { createdAt: "desc" },
take: 10, // Límite de resultados
skip: 0, // Desplazamiento (offset)
});
Incluir relaciones (eager loading):
const usuarioConPosts = await prisma.usuario.findUnique({
where: { id: 1 },
include: {
posts: true,
},
});
Seleccionar solo ciertos campos:
const usuario = await prisma.usuario.findUnique({
where: { id: 1 },
select: {
id: true,
email: true,
nombre: true,
},
});
Actualizar registros
Actualizar un único registro:
const actualizado = await prisma.usuario.update({
where: { id: 1 },
data: { nombre: "Ana García Martínez" },
});
Actualizar múltiples registros:
await prisma.usuario.updateMany({
where: { nombre: { startsWith: "A" } },
data: { nombre: "Actualizado" },
});
Upsert (crear si no existe, actualizar si existe):
const usuario = await prisma.usuario.upsert({
where: { email: "ana@ejemplo.com" },
update: { nombre: "Ana Actualizada" },
create: {
email: "ana@ejemplo.com",
nombre: "Ana García",
},
});
Eliminar registros
Eliminar un único registro:
await prisma.usuario.delete({
where: { id: 1 },
});
Eliminar múltiples registros:
await prisma.usuario.deleteMany({
where: { createdAt: { lt: new Date("2024-01-01") } },
});
Consultas avanzadas
Filtros compuestos
const usuarios = await prisma.usuario.findMany({
where: {
AND: [
{ nombre: { contains: "García" } },
{ createdAt: { gte: new Date("2024-01-01") } },
],
},
});
// OR: al menos una condición
const usuarios = await prisma.usuario.findMany({
where: {
OR: [
{ email: { endsWith: "@empresa.com" } },
{ nombre: { startsWith: "Admin" } },
],
},
});
// NOT: excluir condición
const usuarios = await prisma.usuario.findMany({
where: {
NOT: { email: { contains: "spam" } },
},
});
Relaciones anidadas (nested writes)
// Crear usuario con posts relacionados en una sola operación
const usuario = await prisma.usuario.create({
data: {
email: "nuevo@ejemplo.com",
nombre: "Nuevo Usuario",
posts: {
create: [
{ titulo: "Mi primer post" },
{ titulo: "Mi segundo post" },
],
},
},
include: { posts: true },
});
Agregaciones
// Contar registros
const total = await prisma.usuario.count();
// Contar con filtro
const activos = await prisma.usuario.count({
where: { activo: true },
});
// Aggregate: mín, máx, suma, promedio
const stats = await prisma.pedido.aggregate({
_avg: { total: true },
_max: { total: true },
_min: { total: true },
_sum: { total: true },
});
// GroupBy
const porCategoria = await prisma.producto.groupBy({
by: ["categoria"],
_count: { id: true },
_avg: { precio: true },
});
Transacciones
Transacción secuencial:
await prisma.$transaction(async (tx) => {
const usuario = await tx.usuario.create({
data: { email: "test@test.com", nombre: "Test" },
});
await tx.post.create({
data: { titulo: "Post inicial", autorId: usuario.id },
});
});
Transacción batch (operaciones independientes que se ejecutan juntas):
const [usuarios, posts] = await prisma.$transaction([
prisma.usuario.findMany(),
prisma.post.findMany(),
]);
Comandos útiles del CLI
npx prisma init # Inicializar Prisma en el proyecto
npx prisma generate # Generar/actualizar el cliente
npx prisma migrate dev # Crear y aplicar migración en desarrollo
npx prisma migrate deploy # Aplicar migraciones en producción
npx prisma db push # Sincronizar esquema sin migraciones
npx prisma db pull # Generar esquema desde BD existente (introspección)
npx prisma studio # Abrir explorador visual de datos
npx prisma format # Formatear el archivo schema.prisma
npx prisma validate # Validar el archivo schema.prisma