Prisma 7 з адаптарамі драйвераў NestJS і MySQL
Prisma 7 у глобальным модуле NestJS з сэрвісамі MySQL: кліент на TypeScript, prisma.config.ts і адаптар драйвера MariaDB, такія, што кожны сэрвіс выкарыстоўвае адно.
Prisma — это ORM для Node.js і TypeScript, який керуе схемамі, зв’язкамі та запитамі з типавымі даннем. Prisma 7 змінюе структуру часу виконання: шлях кліента ў дзеярых аспектах стае простэйшым, а ў іншых — строгіяй. Увага тут сконцентравана на налаштаванні Prisma 7 для сервісу NestJS, які взаўмадзейнае з MySQL, а не на стварэнні повнага шаблона Nest з нуля.
Якія ўсё ж змены?
- Prisma Client больш не поставляе бінары на мове Rust.
- Шлях кліента перапісаны на TypeScript і працюе ў звычных рунтаймах JS.
- Генераваны выход кліента знаходзіцца ў выхідных даследах проекту, а не толькі ў папцы
node_modules. - Павторная генерацыя кліента больш не вымагае перезапуску сервера разработкі.
- З’яўляецца новы файл налаштавання Prisma.
- Кожная база дадзеных патрабуе адаптара драйвера.
npx prisma studio.- З’ядзейце пакеты Prisma 7:
npm install @prisma/client@7
npm install -D prisma@7
Prisma 7 не завантажвае зменныя сераўніка автаматычна. Дадзіце dotenv:
npm install dotenv
Прыклады версій Node і npm, якія викорыстоўваліся ў первісных інструкцыях з налаштавання:
node -v
v24.11.1
npm -v
11.6.2
- Створыце пачатковую структуру Prisma:
npx prisma init
Это стварае каталог prisma, у яком знаходзяцца:
schema.prisma— налагоджэнне з’язку і моделіprisma.config.ts— налаштаванні.env— зазвычай данні прыўязкі да базы дадзеных
- З’явіце адаптар MySQL/MariaDB (адаптары практычна розглянутыя ў канцы):
npm install @prisma/adapter-mariadb
- Настроўце URL, месца зберагача схемы, выходны файл для міграцыі і пачатковы данні. У дасведчэннях прыметнае, што файл
prisma.config.tsпавінен знаходзіцца ў корэне проекта разам зpackage.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!
},
});
Частыя проблемы — це PrismaConfigEnvError: Missing required environment variable: DATABASE_URL або скаргі на неабходнасць наявнасці джерела даных для prisma db push. Адна з даследжваных тэм — prisma/prisma#28590.
- Установіце настройкі выходу кліента і задаце модэлі ў схеме:
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
}
- Загорніце кліента ў службу NestJS, якая керуе процесамі падключэння/выключэння:
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');
}
}
- Экспортуйце яго з глобальнага модуля:
import { Module, Global } from '@nestjs/common';
import { PrismaService } from './prisma.service';
@Global()
@Module({
providers: [PrismaService],
exports: [PrismaService],
})
export class PrismaModule {}
- Неабяжна скрыпта-сэдз для тэстовых дадзеных:
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();
});
- Імпортуйце
PrismaModuleу корневы модуль:
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 {}
Калі база дадзеных працюе:
npx prisma generate
npx prisma db push
npx prisma db seed
npm run start:dev
Ігнаруйце створаны выход у git:
/src/generated
Прыклад структуры папак:
└── 📁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
Пераглядайце дадзеныя локальна:
npx prisma studio
Адаптары драйвера
Старэйшы Prisma Client выкарыстоўваў Раст-механізм запытоў, які ператвараў запыты кліента на SQL і ствараў TCP-з’яносы за дапамогою вбудованых драйвераў. Prisma 7 перашыляе процэс компіляцыі ў JavaScript-компілятор запытоў і адмахваецца ад гэтых вбудованых драйвераў. JavaScript-драйверы баз гадзінакоў вярбуюцца з базай гадзінакоў; адаптары драйвераў перакладаюць межу між компіляторам і гэтымі драйверамі. Для MySQL/MariaDB выкарыстоўваецца mariadb адаптар. Паказанае тут матрыцавае спісаванне доступна ў раздзеле документацыі Prisma пра адаптары драйвераў баз гадзінакоў.
Патэрн NestJS выгадвае ад наявнасці адной спаканай інстанцыі кліента на кожны процэс. Стварэнне новага PrismaClient у кожным обробніку запытоў прыводзіць да збільшэння колькасці з’яносоў і ускладнюе розумеенне транзакцый. Вышэўказаны глобальны патэрн модуляў дазволяе, каб адна служба была видна для функцыйных модуляў, а ў той жыткі тэсты маглі заменіць PrismaService на фальшывы экземпляр.
Калі ведаецца регенераванне пасля змян схемы, пераканаецца, што шлях output яшчэ адпавядае імпорту, выкарыстоўванаму ў prisma.service.ts. Неспакоўка между выходам генератора і шляхамі імпорту ёсць частым выкліканнікам адказаў “не можна знайсці модуль” пасля іншым чынам успешных запускаў prisma generate. Зберагаеце moduleFormat у спакоі з тым, як Nest компілюе — неспакоўкі между CommonJS і ESM выражаюцца як тонкія бяговыя адказы, а не як чыстыя адказы компілявання.
Гэтага дастаткова, каб Prisma 7 могла вястацца з MySQL через NestJS за дапамогою адаптароў, файлаў налашчэння і генераванага кліента, які знаходзіцца ў межах кантролю над выконвальным кодам.