Steps to migrate a Prisma schema from implicit to explicit relationshsips.
This repo holds commits for the individual steps:
This is the starting point where the models Post and Category have an implicit relationship managed by Prisma.
model Post {
id Int @id @default(autoincrement())
author User @relation(fields: [authorId], references: [id])
authorId Int // relation scalar field (used in the `@relation` attribute above)
categories Category[]
}
model Category {
id Int @id @default(autoincrement())
posts Post[]
}The database holds a table _CategoryToPost which Prisma uses to manage the relationship
List of relations
Schema | Name | Type | Owner
--------+--------------------+-------+----------
public | Category | table | postgres
public | Post | table | postgres
public | _CategoryToPost | table | postgres
public | _prisma_migrations | table | postgres
(4 rows)Adding fields and a model for an explicit relationship. For clarity the fields used for the implicit relationship were renamed to categoriesImplicit and postsImplicit respectively.
model Post {
id Int @id @default(autoincrement())
author User @relation(fields: [authorId], references: [id])
authorId Int // relation scalar field (used in the `@relation` attribute above)
categoriesImplicit Category[]
categoriesExplicit CategoriesOnPosts[]
}
model Category {
id Int @id @default(autoincrement())
postsImplicit Post[]
postsExplicit CategoriesOnPosts[]
}
model CategoriesOnPosts {
post Post @relation(fields: [postId], references: [id])
postId Int // relation scalar field (used in the `@relation` attribute above)
category Category @relation(fields: [categoryId], references: [id])
categoryId Int // relation scalar field (used in the `@relation` attribute above)
assignedAt DateTime @default(now())
@@id([postId, categoryId])
}Running npx prisma migrate dev updates the database and creates a new table CategoriesOnPosts for the explicit relationship.
List of relations
Schema | Name | Type | Owner
--------+--------------------+-------+----------
public | CategoriesOnPosts | table | postgres
public | Category | table | postgres
public | Post | table | postgres
public | _CategoryToPost | table | postgres
public | _prisma_migrations | table | postgres
(5 rows)Remove the implicit fields from the Prisma schema:
model Post {
id Int @id @default(autoincrement())
author User @relation(fields: [authorId], references: [id])
authorId Int // relation scalar field (used in the `@relation` attribute above)
categoriesExplicit CategoriesOnPosts[]
}
model Category {
id Int @id @default(autoincrement())
postsExplicit CategoriesOnPosts[]
}
model CategoriesOnPosts {
post Post @relation(fields: [postId], references: [id])
postId Int // relation scalar field (used in the `@relation` attribute above)
category Category @relation(fields: [categoryId], references: [id])
categoryId Int // relation scalar field (used in the `@relation` attribute above)
assignedAt DateTime @default(now())
@@id([postId, categoryId])
}
Running npx prisma migrate dev updates the database and removes the table _CategoryToPost as its not needed anymore.
List of relations
Schema | Name | Type | Owner
--------+--------------------+-------+----------
public | CategoriesOnPosts | table | postgres
public | Category | table | postgres
public | Post | table | postgres
public | _prisma_migrations | table | postgres
(4 rows)Now we can rename the fields for the explicit relationship as if nothing had changed. This change does not impact the database as the fields are only represented in the Prisma schema.
model Post {
id Int @id @default(autoincrement())
author User @relation(fields: [authorId], references: [id])
authorId Int // relation scalar field (used in the `@relation` attribute above)
categories CategoriesOnPosts[]
}
model Category {
id Int @id @default(autoincrement())
posts CategoriesOnPosts[]
}
model CategoriesOnPosts {
post Post @relation(fields: [postId], references: [id])
postId Int // relation scalar field (used in the `@relation` attribute above)
category Category @relation(fields: [categoryId], references: [id])
categoryId Int // relation scalar field (used in the `@relation` attribute above)
assignedAt DateTime @default(now())
@@id([postId, categoryId])
}