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!')
}