Install Prisma CLI:
npm install prisma --save-dev
Initialize Prisma in your project:
npx prisma init
Define your data model in schema.prisma
:
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
profile Profile?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId Int
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Profile {
id Int @id @default(autoincrement())
bio String?
user User @relation(fields: [userId], references: [id])
userId Int @unique
}
String
: Text valuesInt
: Integer numbersFloat
: Floating-point numbersBoolean
: True/false valuesDateTime
: Date and time valuesJson
: JSON dataBytes
: Binary data@relation
with @unique
field@relation
on the "many" sideExample of Many-to-Many relation:
model Category {
id Int @id @default(autoincrement())
name String
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
categories Category[]
}
Let's explore a real-world scenario to demonstrate various types of relations in Prisma. We'll model a simple e-commerce system with users, orders, products, and categories.
We'll have the following entities:
model User {
id Int @id @default(autoincrement())
email String @unique
name String
orders Order[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Order {
id Int @id @default(autoincrement())
user User @relation(fields: [userId], references: [id])
userId Int
orderItems OrderItem[]
totalAmount Decimal
status OrderStatus
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
//fields: [userId] indicates that the userId field in the Order model is used to establish this relation.
//references: [id] indicates that the userId field refers to the id field in the User model.
model OrderItem {
id Int @id @default(autoincrement())
order Order @relation(fields: [orderId], references: [id])
orderId Int
product Product @relation(fields: [productId], references: [id])
productId Int
quantity Int
price Decimal
}
model Product {
id Int @id @default(autoincrement())
name String
description String?
price Decimal
stock Int
category Category @relation(fields: [categoryId], references: [id])
categoryId Int
orderItems OrderItem[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Category {
id Int @id @default(autoincrement())
name String
products Product[]
parentCategory Category? @relation("SubCategories", fields: [parentId], references: [id])
parentId Int?
subcategories Category[] @relation("SubCategories")
}
//Category? means this field is optional, as not all categories will necessarily have a parent.
//@relation("SubCategories") specifies the name of the relation. In this case, it is "SubCategories".
//fields: [parentId] indicates that the parentId field in this model is used to establish this relationship.
//references: [id] indicates that the parentId field refers to the id field in the same Category model.
//subcategories Category[] @relation("SubCategories"): This is the reverse side of the self-referential relationship, defining the subcategories of a category.
//Category[] indicates that this field holds an array of Category objects, representing all the subcategories under a given category.
//@relation("SubCategories") specifies the name of the relation, which must match the name used in the parentCategory field.
enum OrderStatus {
PENDING
PROCESSING
SHIPPED
DELIVERED
CANCELLED
}
One-to-Many Relation:
Many-to-Many Relation:
Self-Relation:
One-to-One Relation:
model UserProfile {
id Int @id @default(autoincrement())
bio String?
user User @relation(fields: [userId], references: [id])
userId Int @unique
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String
profile UserProfile?
// ... other fields
}
Here are some example queries using these relations:
const userWithOrders = await prisma.user.findUnique({
where: { id: 1 },
include: { orders: true }
})
const orderWithItems = await prisma.order.findUnique({
where: { id: 1 },
include: {
orderItems: {
include: { product: true }
}
}
})
const categoryWithSubcategories = await prisma.category.findUnique({
where: { id: 1 },
include: {
subcategories: true,
products: true
}
})
Generate Prisma Client:
npx prisma generate
Use Prisma Client in your code:
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
const newUser = await prisma.user.create({
data: {
email: 'john@example.com',
name: 'John Doe',
posts: {
create: {
title: 'My first post',
content: 'This is the content of my first post',
},
},
},
include: {
posts: true,
},
})
// Find a single user
const user = await prisma.user.findUnique({
where: { id: 1 },
include: { posts: true },
})
// Find multiple users
const users = await prisma.user.findMany({
where: { email: { contains: 'example.com' } },
take: 10,
skip: 5,
})
const updatedUser = await prisma.user.update({
where: { id: 1 },
data: { name: 'Jane Doe' },
})
const deletedUser = await prisma.user.delete({
where: { id: 1 },
})
const filteredPosts = await prisma.post.findMany({
where: {
OR: [
{ title: { contains: 'prisma' } },
{ content: { contains: 'database' } },
],
AND: {
published: true,
},
},
})
const sortedUsers = await prisma.user.findMany({
orderBy: {
name: 'asc',
},
})
Use transactions to perform multiple operations atomically:
const [newUser, newPost] = await prisma.$transaction([
prisma.user.create({
data: { name: 'Alice', email: 'alice@example.com' },
}),
prisma.post.create({
data: { title: 'My post', authorId: 1 },
}),
])
Create a migration:
npx prisma migrate dev --name init
Apply migrations to production:
npx prisma migrate deploy
Create a seed file (prisma/seed.ts
):
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function main() {
const alice = await prisma.user.upsert({
where: { email: 'alice@example.com' },
update: {},
create: {
email: 'alice@example.com',
name: 'Alice',
posts: {
create: {
title: 'Check out Prisma with Next.js',
content: 'https://www.prisma.io/nextjs',
published: true,
},
},
},
})
console.log({ alice })
}
main()
.catch((e) => {
console.error(e)
process.exit(1)
})
.finally(async () => {
await prisma.$disconnect()
})
Run the seed script:
npx prisma db seed
Remember to add this script to your package.json
:
{
"prisma": {
"seed": "ts-node prisma/seed.ts"
}
}
2024 © All rights reserved - buraxta.com