تايبسكريبت - تسجيل الدخول مع Prisma 2 و NestJS - مشكلة حقن التبعيات؟


حالياً أنا في مشروعي الأول باستخدام NestJS. أستخدم Prisma 2، وأود تسجيل الاستعلامات في وحدة التحكم في وضع التصحيح، للتعلم والفحص وتجنب مشكلة n+1 وما إلى ذلك!

لقد أنشأت prisma.service.ts:

import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common'
import { PrismaClient } from '@prisma/client'

@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy {
    constructor() {
        super();
    }

    async onModuleInit() {
        await this.$connect()
    }

    async onModuleDestroy() {
        await this.$disconnect()
    }
}

يعمل بشكل جيد، يمكنني استخدامه عبر API والوصول إلى قاعدة البيانات. ومع ذلك، وفقًا لوثائق Prisma 2 حول التسجيل، أحتاج إلى التمرير

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient({
  log: [
    { level: 'warn', emit: 'event' },
    { level: 'info', emit: 'event' },
    { level: 'error', emit: 'event' },
  ],

ثم استخدمه هكذا:

@Injectable()
export class TestService {
    constructor(private prismaService: PrismaService) {
        this.prismaService.$on('query', e => {
            console.log("Query: " + e.query)
            console.log("Duration: " + e.duration + "ms")
        })
    }

للأسف، عند الترجمة أحصل على هذه الأخطاء:

TSError: ⨯ Unable to compile TypeScript:
src/test.service.ts:9:31 - error TS2345: Argument of type '"query"' is not assignable to parameter of type '"beforeExit"'.

9        this.prismaService.$on('query', e => {
                                ~~~~~~~
src/test.service.ts:10:39 - error TS2339: Property 'query' does not exist on type '() => Promise<void>'.

10             console.log("Query: " + e.query)
                                         ~~~~~
src/test.service.ts:11:42 - error TS2339: Property 'duration' does not exist on type '() => Promise<void>'.

11             console.log("Duration: " + e.duration + "ms")

حاولت تمرير مصفوفة log إلى super() في الخدمة، بدون أي نجاح.

هل أفوت شيئًا صغيرًا فقط؟

الإجابة رقم 1

مرحبًا يا أخي، كنت أستخدم prisma 2 + nestjs، لقد وضعت إعدادات prisma في الجزء الأعلى من الأب هكذا. لقد حقق لي نتائج رائعة.

آمل أن يساعدك ;)

هذا هو ملف prismaService.ts الخاص بي

prisma.service.ts
import { INestApplication, Injectable, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
    
    @Injectable()
    export class PrismaService extends PrismaClient implements OnModuleInit {
      constructor() {
        super({
          log: [
            { emit: 'event', level: 'query' },
            { emit: 'stdout', level: 'info' },
            { emit: 'stdout', level: 'warn' },
            { emit: 'stdout', level: 'error' },
          ],
          errorFormat: 'colorless',
        });
      }
      async onModuleInit() {
        await this.$connect();
      }
    
      async enableShutdownHooks(app: INestApplication) {
        this.$on('beforeExit', async (event) => {
          console.log(event.name);
          await app.close();
        });
      }
    }
@Injectable()
export class TestService {
  constructor(private prismaService: PrismaService) {
    prismaService.$on<any>('query', (event: Prisma.QueryEvent) => {
      console.log('Query: ' + event.query);
      console.log('Duration: ' + event.duration + 'ms');
    });
  }
}

ملاحظة: كان عليّ حذف مجلد dist وإعادة التشغيل مرة أخرى.

الإجابة رقم 2

لقد استخدمت هذا الحل الموجود على قضايا GitHub الخاصة بـ Prisma.

@Injectable()
export class TestService {
  constructor(
    private prismaService: PrismaClient<Prisma.PrismaClientOptions, 'query'>,
  ) {
    this.prismaService.$on('query', (e) => {
      console.log('Query: ' + e.query);
      console.log('Duration: ' + e.duration + 'ms');
    });
  }
}