首页 > 解决方案 > Prisma 插入关系一对多

问题描述

我读到 prisma 作为 ORM 提供者,然后决定试一试。我在数据库查询方面的知识,尤其是 postrgres 目前还不是很有经验,所以我遇到了需要一些帮助才能找到正确解决方案的情况。

让我们假设以下内容schema.prisma

model languages {
  language_id                    Int                              @id @default(autoincrement())
  language_code                  String                           @db.VarChar
  translations_categories        translations_categories[]
}

model categories {
  category_id             Int                       @id @default(autoincrement())
  category_name           String                    @db.VarChar
  translations_categories translations_categories[]
}

model translations_categories {
  translation_id    Int        @id @default(autoincrement())
  language_id       Int
  category_id       Int
  translation_value String     @db.VarChar
  categories        categories @relation(fields: [category_id], references: [category_id])
  language          languages  @relation(fields: [language_id], references: [language_id])
}

所以我尝试用一​​些api数据来解决以下更新查询:

  1. 添加一个新类别并插入它category_name
  2. 在其中添加此类别的给定翻译translations_categories(在此步骤中,提供的信息包含language_code,而不是language_id!)

请求正文包含以下字段:

{
  id: 2
  identifier: "TEST-1"
  translations: {
    de: "german", 
    en: "english", 
    fr: "france", 
    it: "italian"
  }
}

出现了以下问题:

  1. 是否可以通过单个查询来实现此工作流程?
  2. 插入时translation,我认为可以通过language_code它自己的提供来实现,不是吗?

标签: sqlpostgresqlprisma

解决方案


我建议以下列方式创建架构:

model languages {
  language_id             Int                       @id @default(autoincrement())
  language_code           String                    @unique
  translations_categories translations_categories[]
}

model categories {
  category_id             Int                       @id @default(autoincrement())
  category_name           String
  translations_categories translations_categories[]
}

model translations_categories {
  translation_id    Int        @id @default(autoincrement())
  language_id       Int
  category_id       Int
  translation_value String
  categories        categories @relation(fields: [category_id], references: [category_id])
  language          languages  @relation(fields: [language_id], references: [language_id])

  @@unique([language_id, category_id])
}

这样做的原因是,language_code对于每种语言来说,它总是独一无二的,因此拥有@unique它会使创建或更新类别变得更加容易。

因此,您可以按如下方式创建/更新类别:

let data = {
  id: 2,
  identifier: 'TEST-1',
  translations: {
    de: 'german',
    en: 'english',
    fr: 'france',
    it: 'italian',
  },
}

let translations = Object.entries(data.translations).map(([key, val]) => ({
  language: {
    connectOrCreate: {
      where: { language_code: key },
      create: { language_code: key },
    },
  },
  translation_value: val,
}))

await prisma.categories.upsert({
  where: { category_id: data.id },
  create: {
    category_name: data.identifier,
    translations_categories: { create: translations },
  },
  update: {
    category_name: data.identifier,
    translations_categories: { create: translations },
  },
})

推荐阅读