Search code examples
javascripttypescriptprisma

Trouble with seeding a db


I preface this with I'm very much a prisma newbie so I'm sure i've made a rookie mistake in either the schema, my seed function, or both.

So I have a couple of models with some 1-n relationships and I'm having issues with seeding them correctly.

These are my models...

model Npc {
  id             Int           @id @default(autoincrement())
  createdAt      DateTime      @default(now())
  name           String
  // An NPC can belong to zero or more factions
  factions       Faction[]
  // An NPC can lead zero or one factions
  factionLeader  Faction?      @relation("FactionLeader")
  // An NPC can have zero locations or one
  locationId     Int?
  location       Location?     @relation(fields: [locationId], references: [id])
  // An NPC can have zero or more relationships
  relationship   Relationship? @relation(fields: [relationshipId], references: [id])
  relationshipId Int?
}

model Relationship {
  id                 Int              @id @default(autoincrement())
  createdAt          DateTime         @default(now())
  // A relationship must have a relationship type
  relationshipTypeId Int
  relationshipType   RelationshipType @relation(fields: [relationshipTypeId], references: [id])
  // a relationship can have zero or more NPCs
  npcs               Npc[]
}

model RelationshipType {
  id           Int            @id @default(autoincrement())
  createdAt    DateTime       @default(now())
  name         String
  // A relationship can have zero or more relationships
  relationship Relationship[]
}

model Faction {
  id             Int       @id @default(autoincrement())
  createdAt      DateTime  @default(now())
  name           String
  // A faction can have zero Leaders or one
  leaderId       Int       @unique
  leader         Npc?      @relation("FactionLeader", fields: [leaderId], references: [id])
  // A faction can have zero or more notable members
  notableMembers Npc[]
}

model Location {
  id            Int            @id @default(autoincrement())
  createdAt     DateTime       @default(now())
  name          String
  // A location can have zero or more NPCs
  npcs          Npc[]
  // A location can have zero or more factions
  factions      Faction[]
}

And these are the functions I'm using to try and seed the db with

const npcData = [
    {
        name: 'Joe Bloggs',
        locationId: 1,
    },
    {
        name: 'Jane Bloggs',
        locationId: 1,
    }
]

const relationshipTypeData = [
    {
        name: 'Familial',
    }
]

const relationshipData = [
    {
        relationshipTypeId: 1,
                npcs: [1, 2],
    }
]

const locationData = [
    {
        name: 'The Great Plains',
        npcs: [1],
    }
]

const factionData = [
    {
        name: 'Tabaxi Caravan',
        leaderId: 1,
        locationId: 1,
                notableMembers: [1],

    }
]

for (const u of userData) {
  const user = await prisma.user.create({
    data: u,
  })
  console.log(`Created user with id: ${user.id}`)
}

for (const r of relationshipData) {
  const relationship = await prisma.relationship.create({
    data: r,
  })
  console.log(`Created relationship with id: ${relationship.id}`)
}

for (const rt of relationshipTypeData) {
  const relationshipType = await prisma.relationshipType.create({
    data: rt,
  })
  console.log(`Created relationship type with id: ${relationshipType.id}`)
}

for (const faction of factionData) {
  const faction = await prisma.faction.create({
    data: f,
  })
  console.log(`Created faction type with id: ${faction.id}`)
}

for (const l of locationData) {
  const location = await prisma.location.create({
    data: l,
  })
  console.log(`Created location with id: ${location.id}`)
}

I'm 99% sure the issue are with the npc arrays but I genuinely am unsure how I should be seeding these relationships do any help would be great.


Solution

  • I would recommend you to try this snippet for seeding:

    const npcData = [
        {
            name: 'Joe Bloggs',
            location: {
                create: {
                    name: 'The Great Plains',
                }
            },
        },
        {
            name: 'Jane Bloggs',
            location: {
                connect: {
                    id: 1,
                }
            },
        }
    ]
    
    const relationshipTypeData = [
        {
            name: 'Familial',
            relationship: {
                create: {
                    npcs: {
                        connect: [
                            { id: 1 },
                            { id: 2 }
                        ]
                    }
                }
            }
        }
    ]
    
    const factionData = [
        {
            name: 'Tabaxi Caravan',
            leader: {
                connect: {
                    id: 1,
                }
            },
            location: {
                connect: {
                    id: 1,
                }
            },
            notableMembers: {
                connect: [
                    { id: 1 },
                ]
            }
        }
    ]
    
    for (const u of npcData) {
      const npc = await prisma.npc.create({
        data: u,
      })
      console.log(`Created npc with id: ${npc.id}`)
    }
    
    for (const rt of relationshipTypeData) {
      const relationshipType = await prisma.relationshipType.create({
        data: rt,
      })
      console.log(`Created relationship type with id: ${relationshipType.id}`)
    }
    
    for (const f of factionData) {
      const faction = await prisma.faction.create({
        data: f,
      })
      console.log(`Created faction type with id: ${faction.id}`)
    }
    

    This code does the following:

    1. Creates NPCs along with their locations.
    2. Creates a relationship type and its relationship to NPCs.
    3. Creates factions and links them to their leader, location, and notable members.

    The create command is used to create a new record and the connect command is used to link an existing record (using its ID). I would recommend you to ensure that the records you are trying to connect already exist in the database.