如何在Prisma的schema.prisma模型中添加自定义元数据并在NestJS中读取
Prisma Schema自定义元数据实现方案
Prisma当前原生没有内置@@metadata这类自定义元数据属性,推荐使用三斜杠文档注释存储结构化元数据,兼容性最好、无额外警告,示例如下:
model role_mapping { id String @id @default(uuid()) @db.VarChar(50) roleId String? @map("role_id") @db.VarChar(50) userId String? @map("user_id") @db.VarChar(50) role role? @relation(fields: [roleId], references: [id]) user user? @relation(fields: [userId], references: [id], onDelete: Restrict, onUpdate: Restrict, map: "role_mapping_ibfk_1") @@unique([roleId, userId], map: "role_id_user_id") @@index([userId], map: "principal_id") @@index([roleId], map: "role_id") /// 自定义元数据: {"coreTable": true, "someOtherMetaData": "自定义值"} }
NestJS中提取自定义元数据的方法
步骤1:安装依赖
使用Prisma官方提供的内部工具解析Schema的元数据结构(DMMF):
npm install @prisma/internals --save-dev
步骤2:实现元数据解析服务
创建全局可用的Prisma元数据服务,模块初始化时自动解析所有模型的自定义元数据:
import { Injectable, OnModuleInit } from '@nestjs/common'; import { getDMMF } from '@prisma/internals'; import * as fs from 'fs'; import * as path from 'path'; // 自定义元数据的类型定义 interface CustomModelMeta { coreTable?: boolean; someOtherMetaData?: any; } @Injectable() export class PrismaMetaService implements OnModuleInit { // 存储所有模型的元数据映射,key为模型名 private metaMap: Map<string, CustomModelMeta> = new Map(); async onModuleInit() { // 读取本地schema文件内容 const schemaPath = path.join(process.cwd(), 'prisma/schema.prisma'); const schemaContent = fs.readFileSync(schemaPath, 'utf-8'); // 解析得到Prisma的元数据结构DMMF const dmmf = await getDMMF({ datamodel: schemaContent }); // 遍历所有模型提取自定义元数据 dmmf.datamodel.models.forEach(model => { if (!model.documentation) return; // 匹配注释中的结构化元数据 const metaReg = /自定义元数据: (\{.*\})/; const matchRes = model.documentation.match(metaReg); if (!matchRes) return; try { const parsedMeta = JSON.parse(matchRes[1]) as CustomModelMeta; this.metaMap.set(model.name, parsedMeta); } catch (err) { console.error(`解析模型${model.name}的自定义元数据失败:`, err); } }); } // 对外暴露的元数据查询方法 getModelMeta(modelName: string): CustomModelMeta | undefined { return this.metaMap.get(modelName); } }
步骤3:业务中使用
将PrismaMetaService注入到需要的业务服务中,直接查询即可:
import { Injectable } from '@nestjs/common'; import { PrismaMetaService } from './prisma-meta.service'; @Injectable() export class YourBusinessService { constructor(private readonly prismaMetaService: PrismaMetaService) {} demo() { // 查询role_mapping模型是否为核心表 const isCoreTable = this.prismaMetaService.getModelMeta('role_mapping')?.coreTable ?? false; console.log('是否为核心表:', isCoreTable); } }
内容的提问来源于stack exchange,提问作者alejandro
相关产品推荐
相关产品推荐

