Enum e Tipi Composti
Enum
Gli enum permettono di definire un insieme fisso di valori possibili per un campo. Sono supportati nativamente da PostgreSQL, MySQL e MongoDB.
Definire un Enum
enum Role {
USER
ADMIN
MODERATOR
EDITOR
}
enum OrderStatus {
PENDING
PROCESSING
SHIPPED
DELIVERED
CANCELLED
}
model User {
id Int @id @default(autoincrement())
name String
role Role @default(USER)
}
model Order {
id Int @id @default(autoincrement())
total Decimal
status OrderStatus @default(PENDING)
}
Usare gli Enum nelle Query
// Creare un utente admin
const admin = await prisma.user.create({
data: {
name: 'Marco',
role: 'ADMIN',
},
})
// Filtrare per ruolo
const moderators = await prisma.user.findMany({
where: {
role: 'MODERATOR',
},
})
// Filtrare con operatore IN
const staff = await prisma.user.findMany({
where: {
role: {
in: ['ADMIN', 'MODERATOR', 'EDITOR'],
},
},
})
// Aggiornare lo stato di un ordine
const order = await prisma.order.update({
where: { id: 1 },
data: {
status: 'SHIPPED',
},
})
Enum con TypeScript
Prisma genera automaticamente i tipi TypeScript per gli enum:
import { Role, OrderStatus } from '@prisma/client'
function isPrivileged(role: Role): boolean {
return role === Role.ADMIN || role === Role.MODERATOR
}
function canCancel(status: OrderStatus): boolean {
return status === OrderStatus.PENDING || status === OrderStatus.PROCESSING
}
Mappare i Valori Enum
Puoi mappare i valori dell’enum a valori diversi nel database:
enum Color {
RED @map("rosso")
GREEN @map("verde")
BLUE @map("blu")
@@map("colori")
}
Tipi Composti (MongoDB)
I tipi composti (composite types) sono disponibili solo con MongoDB. Permettono di definire oggetti embedded direttamente nel documento.
Definire un Tipo Composto
// Usa "type" invece di "model" per i tipi composti
type Address {
street String
city String
zip String
country String
}
type SocialMedia {
platform String
url String
username String?
}
model User {
id String @id @default(auto()) @map("_id") @db.ObjectId
name String
address Address // Oggetto embedded singolo
socials SocialMedia[] // Array di oggetti embedded
}
Operazioni con Tipi Composti
// Creare un utente con indirizzo e social
const user = await prisma.user.create({
data: {
name: 'Giulia',
address: {
street: 'Via Roma 1',
city: 'Milano',
zip: '20100',
country: 'Italia',
},
socials: [
{ platform: 'GitHub', url: 'https://github.com/giulia', username: 'giulia' },
{ platform: 'Twitter', url: 'https://twitter.com/giulia' },
],
},
})
// Filtrare per campo nested
const milanUsers = await prisma.user.findMany({
where: {
address: {
is: {
city: 'Milano',
},
},
},
})
// Aggiornare l'indirizzo
const updated = await prisma.user.update({
where: { id: user.id },
data: {
address: {
update: {
city: 'Roma',
zip: '00100',
},
},
},
})
Tipi Composti Opzionali e Nested
type ContactInfo {
email String
phone String?
address Address? // Tipo composto nested opzionale
}
type Address {
street String
city String
zip String
}
model Company {
id String @id @default(auto()) @map("_id") @db.ObjectId
name String
contact ContactInfo
}
JSON come Alternativa (SQL)
Per i database SQL, se hai bisogno di dati strutturati ma flessibili, puoi usare il tipo Json:
model Product {
id Int @id @default(autoincrement())
name String
attributes Json // Dati strutturati flessibili
metadata Json?
}
// Creare un prodotto con attributi JSON
const product = await prisma.product.create({
data: {
name: 'Laptop Pro',
attributes: {
color: 'silver',
ram: 16,
storage: { type: 'SSD', size: 512 },
ports: ['USB-C', 'HDMI', 'Thunderbolt'],
},
},
})
// Filtrare per campo JSON (PostgreSQL)
const products = await prisma.product.findMany({
where: {
attributes: {
path: ['color'],
equals: 'silver',
},
},
})
Il tipo Json e’ flessibile ma non ha validazione a livello di schema. Per dati fortemente tipizzati, preferisci modelli relazionali separati o tipi composti con MongoDB.