【问题标题】:Updating many-to-many relations in Prisma更新 Prisma 中的多对多关系
【发布时间】:2021-12-04 11:09:11
【问题描述】:

我有一组针对皮肤问题的复选框。用户可以在提交前勾选/取消勾选,也就是说每次提交的皮肤问题集可能都不一样。

我在 Prisma 模式中将其建模为“显式”多对多关系。

model User {
  id                 String                 @id @default(cuid())
  name               String?
  nickname           String?                @unique
  ...
  skinConcerns       SkinConcernsForUsers[]
  ...
}

model SkinConcern {
  id   Int                    @id @default(autoincrement())
  name String                 @unique
  user SkinConcernsForUsers[]
}

model SkinConcernsForUsers {
  user          User        @relation(fields: [userId], references: [id])
  userId        String
  skinConcern   SkinConcern @relation(fields: [skinConcernId], references: [id])
  skinConcernId Int

  @@id([userId, skinConcernId])
}

然后,使用 prisma.skinConcern.createMany 为 SkinConcerns 表播种以下值:

"ACNE",
"DRYNESS",
"OILY_SKIN",
"PIGMENTATION",
"REDNESS",
"WRINKLES",

SkinConcerns 在更新变异输入中以字符串数组的形式出现,例如["PIGMENTATION", "REDNESS"].

我想通过 prisma.user.update 查询为用户 (SkinConcernsForUsers) 更新皮肤问题,但这很棘手,因为我不仅要创建 SkinConcerns,而且还必须连接到现有的皮肤问题集。

我试过直接setting skinConcerns in user,喜欢

await prisma.user.update({
  where: { nickname },
  data: {
    // ... other user data
    skinConcerns: {
      set: [
        {
          skinConcern: {
            connect: { name: "PIGMENTATION" },
          },
        },
        {
          skinConcern: {
            connect: { name: "REDNESS" },
          },
        },
      ],
    },
    // ... other user data
  }
});

在许多其他事情中,但这当然不是一个正确的论点,并且会因错误而失败

Unknown arg `connect` in data.skinConcerns.update.0.where.connect for type SkinConcernsForUsersWhereUniqueInput. Did you mean `select`?
Argument data for data.skinConcerns.update.0.data is missing.
Unknown arg `connect` in data.skinConcerns.update.1.where.connect for type SkinConcernsForUsersWhereUniqueInput. Did you mean `select`?
Argument data for data.skinConcerns.update.1.data is missing.

有没有办法做到这一点?甚至可以在prisma.user.update 中更新它吗?

我想我可以直接更新SkinConcernsForUsers。在这种情况下,我是否应该删除与用户关联但不在用户输入["PIGMENTATION", "REDNESS"] 中的所有行,然后创建不存在的行?它在棱镜代码中会是什么样子?

【问题讨论】:

    标签: prisma


    【解决方案1】:

    首先,我会将您的架构更改为 SkinConcernid 字段不是必需的,并且会在查询中造成复杂性(在尝试连接/断开记录时,您将不必要地需要将每个 name 映射到 id

    name 字段足以作为主键,因为它对于某个记录始终是唯一的。

    更改后的架构如下所示

    model SkinConcern {
      name String                  @id    // name is the new @id. 
      user SkinConcernsForUsers[]
    }
    
    model SkinConcernsForUsers {
      user          User        @relation(fields: [userId], references: [id])
      userId        String
      skinConcern   SkinConcern @relation(fields: [skinConcernName], references: [name])
      skinConcernName String
    
      @@id([userId, skinConcernName])
    }
    
    

    您想要执行的查询可以使用SkinConcernsForUsers 模型分两步执行。

    1. 第 1 步:删除用户连接到的现有 SkinConcernsForUsers 记录。这些不再相关,因为您想覆盖之前的选择。

    2. 第 2 步:使用新选项创建新的 SkinConcernsForUsers 记录。

    这是代码的样子

    
    // step 1
    await prisma.skinConcernsForUsers.deleteMany({
        where: {
            userId: "1",
        },
    });
    
    // step 2
    await prisma.skinConcernsForUsers.createMany({
        data: [
            {
                userId: "1",
                skinConcernName: "REDNESS",
            },
            {
                userId: "1",
                skinConcernName: "PIGMENTATION",
            },
        ],
    });
    

    【讨论】:

    • 谢谢!实际上,这是我在提出这个问题后立即想到的方法,并且我对使用字符串作为主键进行了一些研究。关于 SO 的一般建议是使用自动递增的整数 ID。我认为在我的情况下性能不是什么大问题,但我担心如果我将来必须更改这些键会很头疼(尽管我认为这不太可能)。无论如何,这将使我的工作变得简单得多,因此现在避免一些头痛可能比担心将来可能出现的头痛更好。
    • 乐于助人:)
    • 顺便说一下,对于另一个表,如果我绝对必须有一个整数 ID 作为主键和一个单独的名称列(如我原来的问题),我应该如何解决这个问题?跨度>
    • 你需要某种映射到name_column -> intenger_ID。使用此映射,您可以找到对应的name_columninteger_ID(假设REDNESS 映射到ID 3)。然后,您更改查询以使用 integer_ID 字段代替 name_column(对于我编写的示例查询,您可以将 skinConcernName 更改为 skinConcernId)。
    • 不幸的是,如果您在代码中手动编写它,就没有真正的方法来“保证”同步。我会考虑编写一个小型测试套件来验证数据是否与数据库同步。但正如我之前所说,如果记录数太多,这将非常难以管理,在这种情况下,我只需使用唯一的 name_column 查询数据库以找到匹配的 integer_ID 主键列。
    猜你喜欢
    • 2021-07-23
    • 2021-04-11
    • 2022-01-27
    • 2021-08-24
    • 1970-01-01
    • 2021-09-17
    • 2023-01-27
    • 2021-10-03
    • 2021-06-30
    相关资源
    最近更新 更多