Prisma 7 avec les adaptateurs de pilote NestJS et MySQL
Prisma 7 au sein d’un module global NestJS avec MySQL : le client TypeScript, prisma.config.ts ainsi que l’adaptateur du pilote MariaDB, connectés de manière à ce que chaque service en partage un seul.
Prisma est un ORM pour Node.js et TypeScript qui gère les schémas, les relations et les requêtes typées. Prisma 7 modifie sa structure de fonctionnement : le chemin du client est plus simple à certains égards et plus strict à d’autres. L’objectif ici est de montrer comment intégrer Prisma 7 dans un service NestJS qui communique avec MySQL, et non de créer un squelette Nest complet à partir de zéro.
Quelles sont les modifications ?
- Prisma Client ne fournit plus de binaires natifs en Rust.
- Le chemin du client a été réécrit en TypeScript et s’exécute sur des environnements JS ordinaires.
- Les fichiers générés par le client se trouvent dans la source du projet, et non uniquement sous
node_modules. - La régénération du client ne nécessite plus de redémarrer le serveur de développement.
- Un nouveau fichier de configuration Prisma est apparu.
- Chaque base de données nécessite un adaptateur de pilote.
npx prisma studio.- Installez les paquets Prisma 7 :
npm install @prisma/client@7
npm install -D prisma@7
Prisma 7 ne charge pas automatiquement les variables d’environnement. Ajoutez dotenv :
npm install dotenv
Exemples de versions Node et npm utilisées dans les notes de configuration initiales :
node -v
v24.11.1
npm -v
11.6.2
- Créez la structure de base de Prisma :
npx prisma init
Cela crée un répertoire prisma contenant :
schema.prisma— connexion et modèlesprisma.config.ts— configuration.env— généralement les identifiants de la base de données
- Installez un adaptateur MySQL/MariaDB (les adaptateurs sont abordés à nouveau à la fin) :
npm install @prisma/adapter-mariadb
- Configurez l’URL, l’emplacement du schéma, le résultat de la migration et les données initiales. La documentation exige que
prisma.config.tsse trouve dans la racine du projet à côté depackage.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 piège courant est l’erreur PrismaConfigEnvError: Variable d’environnement requise manquante : DATABASE_URL, ou des plaintes indiquant qu’une source de données est nécessaire pour prisma db push. Une discussion en cours peut être consultée sur prisma/prisma#28590.
- Définissez les résultats affichés par le client et les modèles dans le schéma :
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
}
- Encadrez le client dans un service NestJS qui gère les opérations de connexion/déconnexion :
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');
}
}
- Exportez-le depuis un module global :
import { Module, Global } from '@nestjs/common';
import { PrismaService } from './prisma.service';
@Global()
@Module({
providers: [PrismaService],
exports: [PrismaService],
})
export class PrismaModule {}
- Script de semence optionnel pour les données de test :
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();
});
- Importer
PrismaModuledans le module racine :
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 {}
Avec la base de données en cours d’exécution :
npx prisma generate
npx prisma db push
npx prisma db seed
npm run start:dev
Ignorer les fichiers générés dans git :
/src/generated
Structure typique des dossiers :
└── 📁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
Faire défiler les données localement :
npx prisma studio
Adaptateurs de pilote
La version antérieure du Prisma Client reposait sur un moteur de requêtes Rust qui transformait les appels du client en SQL et établissait des connexions TCP à l’aide de pilotes intégrés. Prisma 7 déplace la compilation vers un compilateur de requêtes JavaScript et élimine ces pilotes intégrés. Les pilotes de base de données JavaScript communiquent avec la base de données ; des adaptateurs de pilotes assurent la traduction entre le compilateur et ces pilotes. Pour MySQL/MariaDB, utilisez l’adaptateur mariadb. Consultez la section des documents Prisma consacrée aux adaptateurs de pilotes de base de données pour obtenir la matrice actuelle.
L’architecture NestJS bénéficie d’une seule instance de client partagée par processus. Créer un nouveau PrismaClient dans chaque gestionnaire de requête multiplie les connexions et rend les transactions plus difficiles à gérer. Le schéma de module global décrit ci-dessus maintient un service visible pour les modules fonctionnels tout en permettant aux tests de remplacer PrismaService par une version fictive.
Lors de la régénération après des modifications du schéma, assurez-vous que le chemin output correspond toujours à l’import utilisé dans prisma.service.ts. Un désaccord entre le résultat du générateur et les chemins d’import est une cause fréquente d’erreurs du type « module non trouvé » après des exécutions réussies de prisma generate. Gardez moduleFormat en accord avec la manière dont Nest compile — les incohérences entre CommonJS et ESM se manifestent par des erreurs de runtime subtiles plutôt que par des échecs de compilation clairs.
Cela suffit pour faire communiquer Prisma 7 avec MySQL depuis NestJS, en utilisant des adaptateurs, des fichiers de configuration et un client généré sous contrôle source.