如何减少 Prisma 选择(或包含)字段代码行

Posted

技术标签:

【中文标题】如何减少 Prisma 选择(或包含)字段代码行【英文标题】:How to reduce Prisma select(or include) field code line 【发布时间】:2021-11-18 00:17:08 【问题描述】:

我正在使用 prisma + express + javascript + mysql 进行开发 棱镜版本是 2.28, 我在使用 prisma 时遇到问题。 当模型是

model User
  id              Int           @id @default(autoincrement())
  email           String        @unique @db.VarChar(30)
  password        String?       @db.VarChar(200)
  nickname        String?       @unique @db.VarChar(30)
  profile         Profile?


model Profile 
  id             Int              @id @default(autoincrement())
  department     String?          @db.VarChar(50)
  introduce      String?          @db.Text
  createdAt      DateTime
  updatedAt      DateTime?
  user           User             @relation(fields: [userId], references: [id])
  userId         Int
  wellTalent     WellTalent[]
  interestTalent InterestTalent[]
  profileImage   Image?

  @@map(name: "profiles")

model InterestTalent 
  id        Int       @id @default(autoincrement())
  contents  String?
  createdAt DateTime
  updatedAt DateTime?
  profile   Profile   @relation(fields: [profileId], references: [id])
  profileId Int

  @@map(name: "interest_talents")


model WellTalent 
  id        Int       @id @default(autoincrement())
  contents  String?
  createdAt DateTime
  updatedAt DateTime?
  profile   Profile   @relation(fields: [profileId], references: [id])
  profileId Int

  @@map(name: "well_talents")


model Image 
  id        Int       @id @default(autoincrement())
  src       String?   @db.VarChar(200)
  createdAt DateTime
  updatedAt DateTime?
  profile   Profile?  @relation(fields: [profileId], references: [id])
  profileId Int?

  @@map(name: "images")


如果我想与用户表一起查找配置文件数据

const prisma = new PrismaClient();

const findByIdWithProfile = async (id) => 
    try 
        return await prisma.user.findUnique(
            where:  id ,
            select: 
                id: true,
                nickname: true,
                email: true,
                profile: 
                    select: 
                        id: true,
                        department: true,
                        introduce: true,
                        wellTalent: 
                            select: 
                                contents: true,
                            ,
                        ,
                        interestTalent: 
                            select: 
                                contents: true,
                            ,
                        ,
                        profileImage: 
                            select: 
                                src: true,
                            ,
                        ,
                    ,
                ,
            ,
        );
     catch (err) 
        console.error(err);
    
;

代码行非常增加.. 我可以分别找到 User 表和 Profile 表,但使用嵌套查询来最小化 DB 访问。 项目越大,情况就越糟糕。 好像是DB结构结构不对,但是替换成本已经太高了,不知道哪种方式最好。 感谢您的帮助

【问题讨论】:

嗨,您能否澄清一下返回非常具体的字段选择是否是一项要求?如果没有必要,那么您可以使用include 而不是select 返回某个关系的所有字段。如果这是一项重要要求,那么恐怕您将不得不像现在一样手动指定字段。您可以做的最好的事情是通过将select 语句的多个键值对放在同一行中,使代码不那么冗长且更易于阅读。 首先,感谢您的评论。使用select 不是一个重要的要求。我只是用它来获取特定数据而不返回需要的id关系(用户表中的密码不同),如果没有要求,使用include是否正确?我认为代码会比select更简洁。我只是想知道是否有 Prisma 提供的功能,或者是否有另一种 db 级别的方法! @TasinIshmam 请编辑问题以将其限制为具有足够详细信息的特定问题,以确定适当的答案。 【参考方案1】:

除非您需要手动控制准确获取哪些字段,否则最好使用 include 关键字。

这是您的查询的更简洁版本,使用 include 关键字而不是 select

const findByIdWithProfile = async (id) => 
    try 
        let data = await prisma.user.findUnique(
            where:  id ,
            include: 
                profile: 
                    include: 
                        wellTalent: true,
                        interestTalent: true,
                        profileImage: true,
                    ,
                ,
            ,
        );
        delete data["password"]; // sensitive information we don't want to expose. 
        return data; 
     catch (err) 
        console.error(err);
    
;

您在 cmets 中提到要省略的唯一字段是 password。在这里,我在获取数据后使用delete 关键字手动省略了该字段。目前没有 Prisma 功能可以明确“排除”某些字段但保留其他所有内容。但是,此功能目前正在开发中,应该很快就会推出。您可以在this github issue 跟踪进度。

【讨论】:

你建议的方法看起来很不错。我知道删除方法,但我没有想到它。谢谢,我希望尽快提供从架构中排除的方法。 乐于助人。请随时join our slack 获取定期功能更新或询问您是否有任何问题!

以上是关于如何减少 Prisma 选择(或包含)字段代码行的主要内容,如果未能解决你的问题,请参考以下文章

Prisma 模式 - 从多个可能的外键(或关系)创建关系字段

NestJS-Prisma 如何使用关系字段创建记录?

Prisma:字段...未在...输入类型或类型中定义...预期但未提交对象

节点 express-graphql 应用程序中使用的 Prisma 2 DateTime 字段

PRISMA:如何在 prisma 常规类型中跳过 id 字段?

prisma2:如何获取嵌套字段?