【问题标题】:Update multiple rows using Prisma without manual loops使用 Prisma 更新多行,无需手动循环
【发布时间】:2023-02-01 07:03:45
【问题描述】:

我有以下 prisma.schema:

model Tag {
  id    Int       @id @default(autoincrement())
  name  String    @unique
  files FileTag[]
}

model FileTag {
  tag    Tag  @relation(fields: [tagId], references: [id], onDelete: Cascade)
  tagId  Int
  file   File @relation(fields: [fileId], references: [id], onDelete: Cascade)
  fileId Int

  @@id([fileId, tagId])
}

这是我更新数据库的代码:

for (const tagId of tagIds){
    const tag = await Tags.addFileToTag(parseInt(tagId), fileId);
};

async addFileToTag(tagId: number, fileId: number) {
    const client = await getDbClient();

    return await client.tag.update({
      where: {
        id: tagId,
      },

      data: {
        files: {
          create: {
            fileId
          }
        }
      }
    })
  }

这个实现达到了我的目标。但问题是,我不喜欢这个实现。我正在使用一个循环并调用相同的更新反复查询。

现在,我想知道是否有任何替代程序,(即改变 prisma更新更新很多查询)通过删除循环...这将对数据库进行相同的更改?

【问题讨论】:

    标签: postgresql prisma


    【解决方案1】:

    updateMany 用于更新多行中的相同数据,但在您的情况下,您想更新不同的数据,因此 updateMany 在这里没有用。

    您可以选择使用 transactions 如果需要原子性并且需要确保所有标签都已更新,或者如果有任何错误则没有标签被更新。

    【讨论】:

      【解决方案2】:

      我在 NestJs 项目中使用 Prisma 时遇到了类似的问题,我将我的解决方案留在这里,这可能有一天对某人有帮助。

      我有这样的事情:

      model Job {
        id                  Int @id @default(autoincrement())
        authorId            Int
        position            String
        type                String
        description         String
        requirement         String
        requirementItems    RequirementItem[] 
        task                String
        location            String
        company             String
        companyWebsite      String  
        createdAt           DateTime @default(now())
        updatedAt           DateTime @updatedAt
        author              User @relation(fields: [authorId], references: [id], onDelete: Cascade)
        application         Application[]
      
      }
      
      model RequirementItem {
        jobId     Int
        item      String
        job       Job     @relation(fields: [jobId], references: [id], onDelete: Cascade)
      }
      

      我必须使用来自前端的新值更新 Job 模型和 RequirementItem。

      我不确定我的解决方案是最好的,但我删除了 RequirementItem 中具有相同 jobId 的所有项目,并在相同的查询中使用新值创建它们,如下所示:

      async editJob(jobId: number, job: CreateJobDto, userId: number) {
          const publishedJob = await this.prisma.job.findUnique({
            where: {
              id: jobId,
            },
          });
      
          if (!publishedJob) {
            throw new NotFoundException('There is no job with this id');
          }
      
          if (publishedJob.authorId !== userId) {
            throw new ForbiddenException(
              "You cannot edit a job that you didn't published",
            );
          }
      
          const { requirementItems, taskItems } = job;
      
          return await this.prisma.job.update({
            where: { id: jobId },
            data: {
              ...job,
              requirementItems: {
                // deleted all records
                deleteMany: {
                  jobId: jobId,
                },
                // created new records
                create: requirementItems,
              },
            },
          });
        }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-12-07
        • 2015-07-28
        • 2021-11-25
        • 1970-01-01
        • 2022-01-22
        • 2023-03-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多