Галоўная / Артыкулы

Prisma 7 з адаптарамі драйвераў NestJS і MySQL

Prisma 7 у глобальным модуле NestJS з сэрвісамі MySQL: кліент на TypeScript, prisma.config.ts і адаптар драйвера MariaDB, такія, што кожны сэрвіс выкарыстоўвае адно.

Выдавец: REACTAPP.TOP5 хв чытання1112 слоў

Крыніцы: Get Started With Prisma 7 with Nest Js & MySQL

Prisma — это ORM для Node.js і TypeScript, який керуе схемамі, зв’язкамі та запитамі з типавымі даннем. Prisma 7 змінюе структуру часу виконання: шлях кліента ў дзеярых аспектах стае простэйшым, а ў іншых — строгіяй. Увага тут сконцентравана на налаштаванні Prisma 7 для сервісу NestJS, які взаўмадзейнае з MySQL, а не на стварэнні повнага шаблона Nest з нуля.

Якія ўсё ж змены?

  • Prisma Client больш не поставляе бінары на мове Rust.
  • Шлях кліента перапісаны на TypeScript і працюе ў звычных рунтаймах JS.
  • Генераваны выход кліента знаходзіцца ў выхідных даследах проекту, а не толькі ў папцы node_modules.
  • Павторная генерацыя кліента больш не вымагае перезапуску сервера разработкі.
  • З’яўляецца новы файл налаштавання Prisma.
  • Кожная база дадзеных патрабуе адаптара драйвера.
  • Створаны кліент не залежыць ад базы дадзеных: ён уважае толькі структуру схемы, а не бінарны код вбудованага двайчарога.
  • Prisma Studio запускаецца за дапамою npx prisma studio.
  • Падтрымліваюцца картыраваныя enum-ы.
    1. З’ядзейце пакеты 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
    
    1. Створыце пачатковую структуру Prisma:
    npx prisma init
    

    Это стварае каталог prisma, у яком знаходзяцца:

    • schema.prisma — налагоджэнне з’язку і моделі
    • prisma.config.ts — налаштаванні
    • .env — зазвычай данні прыўязкі да базы дадзеных
    1. З’явіце адаптар MySQL/MariaDB (адаптары практычна розглянутыя ў канцы):
     npm install @prisma/adapter-mariadb
    
    1. Настроўце 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.

    1. Установіце настройкі выходу кліента і задаце модэлі ў схеме:
    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
    }
    
    1. Загорніце кліента ў службу 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');
      }
    }
    
    1. Экспортуйце яго з глобальнага модуля:
    import { Module, Global } from '@nestjs/common';
    import { PrismaService } from './prisma.service';
    
    @Global()
    @Module({
      providers: [PrismaService],
      exports: [PrismaService],
    })
    export class PrismaModule {}
    
    1. Неабяжна скрыпта-сэдз для тэстовых дадзеных:
    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();
      });
    
    1. Імпортуйце 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 за дапамогою адаптароў, файлаў налашчэння і генераванага кліента, які знаходзіцца ў межах кантролю над выконвальным кодам.