🌯

Prismaでお互いに外部キー参照するときの書き方

2023/11/02に公開

prismaschema.prismaの作成の際にお互いに外部キーのリレーションがある場合の備忘録です。
お互いに参照している場合は@relationnameをつけて参照する必要があるみたいです。
じゃないと、
…Please provide different relation names for them by adding `@relation(<name>).
みたいに怒られました。

schema.prisma
model User {
  user_id         String     @id @default(cuid())
  user_name       String?    @db.VarChar(30)
  image           Image?     @relation(name: "selectImage", fields: [image_id], references: [image_id], onDelete: SetNull)
  image_id        Int?
  images          Image[]    @relation("createUser")
  
  @@map(name: "users")
}

model Image {
  image_id        Int      @id @default(autoincrement())
  create_user     User     @relation(name: "createUser", fields: [create_user_id], references: [user_id], onDelete: Cascade)
  create_user_id  String
  users           User[]   @relation("selectImage")

  @@map(name: "images")
}

ただこのときに一気にseedするのが、わからなくて、
userを作って→imageを作って→userをアップデートする
みたいにくどい方法になってしまいました。いい方法はないのかな。

seed.ts
import { Prisma, PrismaClient } from '@prisma/client';

const prisma = new PrismaClient({ log: ['query'] })
async function main() {
  const users: Prisma.UserCreateInput[] = [
    {
      user_name: 'test',
      email: 'test@test.com',
    },
    ...
  ]
  await Promise.all(
    [
       ...users.map(async (user) => {
          await prisma.user.create({
          data: user,
          })
       }),
    ])

  const findUser = await prisma.user.findUnique({
    where:{
      email:'test@test.com'
    },
  }) 

  const images: Prisma.ImageCreateInput[] = [
    {
      create_user:{
        connect:{
          user_id:findUser?.user_id,
        }
      },
    },
    ...
  ]
  await Promise.all(
    [
      ...images.map(async (image) => {
        await prisma.image.create({
          data: image,
        })
      }),
    ]
  )
  await prisma.user.updateMany({
    data:{
      image_id:1
    }
  });
}

main()
  .then(async () => {
    await prisma.$disconnect()
  })
  .catch(async (e) => {
    console.error(e)
    await prisma.$disconnect()
    process.exit(1)
  })

Discussion