'How to seed with relationships in Prisma

I'm playing around with seeding in Prisma and I'm struggling to find examples that aren't super basic. In the example below, I want to create a User (author) who has authored multiple Services (1:n) and each Service has can come from one Provider.

  • User - 1:n - Services
  • Services m:1 - Provider

In the example below, the creation process results in 3 instances of "AWS" on the Provider table. Which, makes sense given the syntax used. I'd like to just have one Record of AWS, GCP, and AZURE (my provider enums) respectively.

Also, if anyone has a more eloquent example of how to generate this to be more scalable of a seed please let me know.

seed.ts

const main = async () => {
  await prisma.user.create({
    data: {
      email: "[email protected]",
      username: "timothy",
      role: "MODERATOR",
      authored: {
        create: [
          {
            name: "Simple Storage Service",
            acronym: "S3",
            provider: {
              create: {
                name: "AWS", // how can these all reference the same Provider table row?
              },
            },
          },
          {
            name: "DynamoDB",
            acronym: "DynamoDB",
            provider: {
              create: {
                name: "AWS",
              },
            },
          },
          {
            name: "API Gateway",
            acronym: "API Gateway",
            provider: {
              create: {
                name: "AWS",
              },
            },
          },
          {
            name: "BigQuery",
            acronym: "BigQuery",
            provider: {
              create: {
                name: "GCP",
              },
            },
          },
        ],
      },
    },
  });
};

schema.prisma

enum Providers {
  AWS
  GCP
  AZURE
}

enum Role {
  USER
  MODERATOR
  ADMIN
}

model User {
  id        Int       @id @default(autoincrement())
  email     String    @unique @db.VarChar(255)
  username  String    @unique @db.VarChar(255)
  role      Role      @default(USER)
  createdAt DateTime  @default(now())
  authored  Service[]
}

model Service {
  id         Int      @id @default(autoincrement())
  name       String   @unique @db.VarChar(255)
  acronym    String   @unique @db.VarChar(255)
  authorId   Int
  providerId Int
  author     User     @relation(fields: [authorId], references: [id])
  provider   Provider @relation(fields: [providerId], references: [id])
  createdAt  DateTime @default(now())
  updatedAt  DateTime @updatedAt
}

model Provider {
  id        Int       @id @default(autoincrement())
  name      Providers
  Services  Service[]
  createdAt DateTime  @default(now())
}

Current result in the Provider's table. There should not be duplicates (triplicates) of "AWS".

enter image description here



Solution 1:[1]

Just precreate provider and then connect it to the service:

const main = async () => {
  const awsProvider = await prisma.providers.create({
    data: { name: 'AWS' }
  })

  await prisma.user.create({
    data: {
      email: "[email protected]",
      username: "timothy",
      role: "MODERATOR",
      authored: {
        create: [
          {
            name: "Simple Storage Service",
            acronym: "S3",
            provider: {
              connect: awsProvider
            },
          },

// ...

Solution 2:[2]

I've resolved the issue, the example below shows how to connect or associate the tables in the seed.

here are the relevant Prisma docs.

const main = async () => {
  const awsProvider = await prisma.provider.create({
    data: { name: "AWS" },
  });
  const gcpProvider = await prisma.provider.create({
    data: { name: "GCP" },
  });

  await prisma.user.create({
    data: {
      email: "[email protected]",
      username: "timothy",
      role: "MODERATOR",
      authored: {
        create: [
          {
            name: "Simple Storage Service",
            acronym: "S3",
            provider: {
              connect: { id: awsProvider.id },
            },
          },
          {
            name: "DynamoDB",
            acronym: "DynamoDB",
            provider: {
              connect: { id: awsProvider.id },
            },
          },
          {
            name: "API Gateway",
            acronym: "API Gateway",
            provider: {
              connect: { id: awsProvider.id },
            },
          },
          {
            name: "BigQuery",
            acronym: "BigQuery",
            provider: {
              connect: { id: gcpProvider.id },
            },
          },
        ],
      },
    },
  });
};

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Danila
Solution 2 kevin