00
:
00
:
00
:
00
Corso SEO AI - Usa SEOEMAIL al checkout per il 30% di sconto

Seeding del Database

Cos’e’ il Seeding?

Il seeding e’ il processo di popolamento del database con dati iniziali. E’ utile per:

  • Avere dati di test durante lo sviluppo.
  • Inserire dati fissi necessari all’applicazione (ruoli, categorie, ecc.).
  • Popolare ambienti di staging con dati realistici.

Configurazione

1. Creare lo Script di Seed

Crea il file prisma/seed.ts:

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

async function main() {
  // Pulire i dati esistenti (opzionale)
  await prisma.post.deleteMany()
  await prisma.user.deleteMany()

  // Creare utenti
  const alice = await prisma.user.create({
    data: {
      email: 'alice@example.com',
      name: 'Alice',
      role: 'ADMIN',
      posts: {
        create: [
          {
            title: 'Introduzione a Prisma',
            content: 'Prisma e\' un ORM moderno per TypeScript...',
            published: true,
          },
          {
            title: 'Query avanzate',
            content: 'Scopriamo le query avanzate di Prisma...',
            published: false,
          },
        ],
      },
    },
  })

  const bob = await prisma.user.create({
    data: {
      email: 'bob@example.com',
      name: 'Bob',
      role: 'USER',
      posts: {
        create: {
          title: 'Il mio primo post',
          content: 'Ciao mondo!',
          published: true,
        },
      },
    },
  })

  console.log('Seed completato:', { alice, bob })
}

main()
  .catch((e) => {
    console.error('Errore durante il seed:', e)
    process.exit(1)
  })
  .finally(async () => {
    await prisma.$disconnect()
  })

2. Configurare package.json

Aggiungi la configurazione del seed nel package.json:

{
  "prisma": {
    "seed": "ts-node --compiler-options {\"module\":\"CommonJS\"} prisma/seed.ts"
  }
}

Per progetti con ESM (ES Modules):

{
  "prisma": {
    "seed": "npx tsx prisma/seed.ts"
  }
}

3. Eseguire il Seed

# Eseguire manualmente
npx prisma db seed

# Il seed viene eseguito automaticamente dopo:
npx prisma migrate dev
npx prisma migrate reset

Seed con Dati Fake (Faker.js)

Installa la libreria per generare dati realistici:

npm install @faker-js/faker --save-dev
import { PrismaClient } from '@prisma/client'
import { faker } from '@faker-js/faker/locale/it'

const prisma = new PrismaClient()

async function main() {
  // Creare 50 utenti con post casuali
  for (let i = 0; i < 50; i++) {
    const numPosts = faker.number.int({ min: 0, max: 5 })

    await prisma.user.create({
      data: {
        email: faker.internet.email(),
        name: faker.person.fullName(),
        bio: faker.lorem.sentence(),
        avatar: faker.image.avatar(),
        posts: {
          create: Array.from({ length: numPosts }, () => ({
            title: faker.lorem.sentence(),
            content: faker.lorem.paragraphs(3),
            published: faker.datatype.boolean(),
            createdAt: faker.date.past(),
          })),
        },
      },
    })
  }

  // Creare categorie fisse
  const categories = ['Tecnologia', 'Design', 'Business', 'Scienza', 'Sport']
  for (const name of categories) {
    await prisma.category.upsert({
      where: { name },
      update: {},
      create: { name },
    })
  }

  console.log('Seed con dati fake completato!')
}

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

Seed Condizionale

Evita duplicati usando upsert o controllando l’esistenza dei dati:

async function main() {
  // Upsert: crea solo se non esiste, altrimenti aggiorna
  const admin = await prisma.user.upsert({
    where: { email: 'admin@example.com' },
    update: { name: 'Admin' },
    create: {
      email: 'admin@example.com',
      name: 'Admin',
      role: 'ADMIN',
    },
  })

  // Controllo esplicito
  const userCount = await prisma.user.count()
  if (userCount === 0) {
    console.log('Database vuoto, inserimento dati iniziali...')
    // ... inserisci dati
  } else {
    console.log(`Database gia' popolato con ${userCount} utenti.`)
  }

  // CreateMany: ignora i duplicati (skipDuplicates)
  await prisma.category.createMany({
    data: [
      { name: 'Tech' },
      { name: 'Design' },
      { name: 'Business' },
    ],
    skipDuplicates: true,
  })
}

Seed con Transazioni

Per garantire che tutti i dati vengano inseriti in modo atomico:

async function main() {
  await prisma.$transaction(async (tx) => {
    const user = await tx.user.create({
      data: { email: 'test@example.com', name: 'Test' },
    })

    await tx.post.createMany({
      data: [
        { title: 'Post 1', authorId: user.id },
        { title: 'Post 2', authorId: user.id },
        { title: 'Post 3', authorId: user.id },
      ],
    })

    await tx.profile.create({
      data: { userId: user.id, bio: 'Utente di test' },
    })
  })

  console.log('Seed transazionale completato!')
}