Prisma 7 con adaptadores de controlador para NestJS y MySQL
Prisma 7 dentro de un módulo global de NestJS con MySQL: el cliente de TypeScript, prisma.config.ts y el adaptador del controlador MariaDB, conectados de modo que cada servicio comparta el mismo.
Prisma es un ORM para Node.js y TypeScript que gestiona esquemas, relaciones y consultas tipadas. Prisma 7 modifica la estructura del entorno de ejecución: el camino del cliente es más simple en algunos aspectos y más estricto en otros. El foco aquí está en la configuración de Prisma 7 para un servicio NestJS que se comunica con MySQL, no en un scaffold completo de Nest desde cero.
¿Cuáles son los cambios?
- Prisma Client ya no incluye binarios nativos en Rust.
- El camino del cliente se ha reescrito en TypeScript y funciona en entornos de ejecución normales de JS.
- Los resultados generados por el cliente se encuentran en la fuente del proyecto, y no solo dentro de
node_modules. - La regeneración del cliente ya no requiere reiniciar el servidor de desarrollo.
- Aparece un nuevo archivo de configuración de Prisma.
- Cada base de datos necesita un adaptador de controlador.
npx prisma studio.- Instale los paquetes de Prisma 7:
npm install @prisma/client@7
npm install -D prisma@7
Prisma 7 no carga automáticamente las variables de entorno. Añada dotenv:
npm install dotenv
Ejemplos de versiones de Node y npm utilizadas en las notas iniciales de configuración:
node -v
v24.11.1
npm -v
11.6.2
- Cree la estructura inicial de Prisma:
npx prisma init
Eso crea un directorio prisma que contiene:
schema.prisma— conexión y modelosprisma.config.ts— configuración.env— generalmente credenciales de la base de datos
- Instale un adaptador de MySQL/MariaDB (los adaptadores se tratan nuevamente al final):
npm install @prisma/adapter-mariadb
- Configure la URL, la ubicación del esquema, la salida de las migraciones y los datos iniciales. La documentación espera que
prisma.config.tsse encuentre en la raíz del proyecto junto apackage.json.
.env:
DATABASE_URL="mysql://test_user:test_password@localhost:3306/test_db"
prisma.config.ts:
// This file was generated by Prisma and assumes you have installed the following:
// npm install --save-dev prisma dotenv
import "dotenv/config";
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
seed: 'tsx prisma/seed.ts',
},
datasource: {
url: process.env.DATABASE_URL!
},
});
Un error común es PrismaConfigEnvError: Variable de entorno requerida faltante: DATABASE_URL, o quejas sobre la necesidad de una fuente de datos para prisma db push. Una discusión relacionada se encuentra en prisma/prisma#28590.
- Establezca la salida del cliente y defina los modelos en el esquema:
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
moduleFormat = "cjs" //Matches Prisma's output format with NestJS's CommonJS runtime environment.
}
datasource db {
provider = "mysql"
}
// Example model
model user {
id Int @id @default(autoincrement())
email String @unique
name String?
password String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
- Abrigue al cliente en un servicio de NestJS que se encargue de las operaciones de conexión/desconexión:
import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
import { PrismaClient } from '../src/generated/prisma/client';
import { PrismaMariaDb } from '@prisma/adapter-mariadb';
@Injectable()
export class PrismaService
extends PrismaClient
implements OnModuleInit, OnModuleDestroy
{
constructor() {
const adapter = new PrismaMariaDb(process.env.DATABASE_URL!);
super({ adapter, log: ['info', 'warn', 'error'] });
}
async onModuleInit() {
try {
await this.$connect();
await this.$queryRaw`SELECT 1`;
console.log('✅ Prisma connected to MySQL');
} catch (error) {
console.error('❌ Prisma connection error:', error);
throw error;
}
}
async onModuleDestroy() {
await this.$disconnect();
console.log('🔌 Prisma disconnected from MySQL');
}
}
- Exportéelo desde un módulo global:
import { Module, Global } from '@nestjs/common';
import { PrismaService } from './prisma.service';
@Global()
@Module({
providers: [PrismaService],
exports: [PrismaService],
})
export class PrismaModule {}
- Script de semilla opcional para datos de prueba:
import { PrismaClient } from '../src/generated/prisma/client';
import { PrismaMariaDb } from '@prisma/adapter-mariadb';
import 'dotenv/config';
const adapter = new PrismaMariaDb(process.env.DATABASE_URL!);
const prisma = new PrismaClient({ adapter });
async function main() {
console.log('🌱 Starting database seeding...');
// Check if database already has data
const userCount = await prisma.user.count();
if (userCount > 0) {
console.log('⚠️ Database already contains data. Skipping seed.');
console.log(` Found ${userCount} users in the database.`);
return;
}
console.log('📭 Database is empty. Starting seed...');
// Hash password for users
const hashedPassword = 'test12345';
// Create users
const user1 = await prisma.user.create({
data: {
email: 'robot@gmail.com',
name: 'Mr Robot',
password: hashedPassword,
},
});
console.log('✅ Created users');
}
main()
.catch((e) => {
console.error('❌ Error during seeding:', e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});
- Importar
PrismaModuleal módulo raíz:
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { AuthModule } from './modules/auth/auth.module';
import { ConfigModule } from '@nestjs/config';
import { PrismaModule } from 'prisma/prisma.module';
@Module({
imports: [AuthModule, PrismaModule, ConfigModule.forRoot()],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Con la base de datos en ejecución:
npx prisma generate
npx prisma db push
npx prisma db seed
npm run start:dev
Ignorar la salida generada en git:
/src/generated
Ejemplo de estructura de carpetas:
└── 📁backend
└── 📁prisma
├── prisma.module.ts
├── prisma.service.ts
├── schema.prisma
├── seed.ts
└── 📁src
└── 📁generated
└── 📁prisma
└── 📁modules
└── 📁auth
├── app.controller.spec.ts
├── app.controller.ts
├── app.module.ts
├── app.service.ts
├── main.ts
├── .env
├── .gitignore
├── .prettierrc
├── eslint.config.mjs
├── nest-cli.json
├── package-lock.json
├── package.json
├── prisma.config.ts
├── README.md
├── tsconfig.build.json
└── tsconfig.json
Navegar por los datos localmente:
npx prisma studio
Adaptadores de controlador
La versión anterior del Prisma Client dependía de un motor de consultas en Rust que convertía las solicitudes del cliente en SQL y establecía conexiones TCP mediante controladores integrados. Prisma 7 traslada la compilación a un compilador de consultas en JavaScript y elimina esos controladores incorporados. Los controladores de base de datos en JavaScript se comunican con la base de datos; los adaptadores de controlador realizan la traducción entre el compilador y dichos controladores. Para MySQL/MariaDB, utilice el adaptador mariadb. Consulte la sección de documentación de Prisma sobre adaptadores de controlador de base de datos para conocer la matriz actual.
NestJS se beneficia al contar con una única instancia de cliente compartida por proceso. Crear un nuevo PrismaClient en cada manejador de solicitudes multiplica las conexiones y dificulta el razonamiento sobre las transacciones. El patrón de módulo global mencionado anteriormente mantiene un servicio visible para los módulos de funcionalidades, al tiempo que permite a las pruebas reemplazar PrismaService por uno falso.
Al regenerar después de editar el esquema, confirme que la ruta output siga coincidiendo con la importación utilizada en prisma.service.ts. Una discrepancia entre la salida del generador y las rutas de importación es una causa común de errores “no se puede encontrar módulo” tras ejecuciones exitosas de prisma generate. Mantenga moduleFormat alineado con la forma en que Nest compila: las discrepancias entre CommonJS y ESM se manifiestan como errores sutiles en tiempo de ejecución en lugar de fallos claros durante la compilación.
Eso es suficiente para que Prisma 7 se comunique con MySQL desde NestJS mediante adaptadores, archivos de configuración y un cliente generado, todo dentro de los límites del control de versiones.
Lecturas relacionadas
- Empezando con Prisma en Node.js y PostgreSQL — Instalar Prisma, inicializar un esquema de PostgreSQL, migrar datos, generar el cliente y ejecutar las primeras consultas de lectura y escritura.
- Configurando Prisma 7 con Accelerate URLs — Explorar prisma.config.ts, los argumentos del constructor, los protocolos accelerateURL y la configuración dual de DATABASE_URL en Prisma 7.