#6917 04c54a4eb
Thanks @mitchellhamilton! - The names of one-sided and two-sided, many-many relationships has been shortened. Two-sided many-many relationship names contain only the left-hand side names now; and the _many
suffix has been dropped from one-sided many-many relationships.
This reduces the probability that you will exceed PostgreSQL's 63 character limit for identifiers with typical usage.
This is a breaking change.
There are two ways to update:
Set db.relationName
on many to many relation
Rather than doing a migration, you can set the new field property db.relationName
, for either side of a many-to-many relationship field.
If set to the existing relation name, your database will remain unchanged.
For example, given a schema like this:
Post: list({
fields: {
tags: relationship({ ref: 'Tag.posts', many: true }),
},
}),
Tag: list({
fields: {
posts: relationship({ ref: 'Post.tags', many: true }),
},
}),
Before this release, the generated Prisma schema looked like this:
datasource postgresql {
url = env("DATABASE_URL")
provider = "postgresql"
}
generator client {
provider = "prisma-client-js"
output = "node_modules/.prisma/client"
engineType = "binary"
}
model Post {
id String @id @default(cuid())
tags Tag[] @relation("Post_tags_Tag_posts")
}
model Tag {
id String @id @default(cuid())
posts Post[] @relation("Post_tags_Tag_posts")
}
By adding db: { relationName: 'Post_tags_Tag_posts' }
to one side of the many-to-many relationship; you can preclude yourself from a migration.
Note: It doesn't matter which side of the relationship you put this property, but it should be only on one side; otherwise you will receive an error.
Post: list({
fields: {
tags: relationship({ ref: 'Tag.posts', many: true, db: { relationName: 'Post_tags_Tag_posts' } }),
},
}),
Tag: list({
fields: {
posts: relationship({ ref: 'Post.tags', many: true }),
},
}),
Rename your many relation tables using a migration
For example, given a schema like this:
Post: list({
fields: {
tags: relationship({ ref: 'Tag.posts', many: true }),
},
}),
Tag: list({
fields: {
posts: relationship({ ref: 'Post.tags', many: true }),
},
}),
When updating to this change, and running npm run dev
, Keystone will prompt you to update your schema.
If you are using useMigrations: true
, Keystone will follow the typical migration flow offer to apply an automatically generated migration. DO NOT APPLY THE AUTOMATICALLY GENERATED MIGRATION - unless you want to DROP
your data.
If you are using useMigrations: false
, Keystone will follow the typical flow and offer to automatically migrate your schema. Again, DO NOT RUN THE AUTOMATIC MIGRATION - unless you want to DROP
your data.
On PostgreSQL, Prisma will generate a migration that looks something like this:
-- DropForeignKey
ALTER TABLE "_Post_tags_Tag_posts" DROP CONSTRAINT "_Post_tags_Tag_posts_A_fkey";
-- DropForeignKey
ALTER TABLE "_Post_tags_Tag_posts" DROP CONSTRAINT "_Post_tags_Tag_posts_B_fkey";
-- DropTable
DROP TABLE "_Post_tags_Tag_posts";
-- CreateTable
CREATE TABLE "_Post_tags" (
"A" TEXT NOT NULL,
"B" TEXT NOT NULL
);
-- CreateIndex
CREATE UNIQUE INDEX "_Post_tags_AB_unique" ON "_Post_tags"("A", "B");
-- CreateIndex
CREATE INDEX "_Post_tags_B_index" ON "_Post_tags"("B");
-- AddForeignKey
ALTER TABLE "_Post_tags" ADD FOREIGN KEY ("A") REFERENCES "Post"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_Post_tags" ADD FOREIGN KEY ("B") REFERENCES "Tag"("id") ON DELETE CASCADE ON UPDATE CASCADE;
You need to modify it so that it looks like this with the old and new table names for your schema substituted:
ALTER TABLE "_Post_tags_Tag_posts" RENAME TO "_Post_tags";
ALTER INDEX "_Post_tags_Tag_posts_AB_unique" RENAME TO "_Post_tags_AB_unique";
ALTER INDEX "_Post_tags_Tag_posts_B_index" RENAME TO "_Post_tags_B_index";
ALTER TABLE "_Post_tags" RENAME CONSTRAINT "_Post_tags_Tag_posts_A_fkey" TO "_Post_tags_A_fkey";
ALTER TABLE "_Post_tags" RENAME CONSTRAINT "_Post_tags_Tag_posts_B_fkey" TO "_Post_tags_B_fkey";
On SQLite, Prisma will generate a migration that looks something like this:
-- DropTable
PRAGMA foreign_keys=off;
DROP TABLE "_Post_tags_Tag_posts";
PRAGMA foreign_keys=on;
-- CreateTable
CREATE TABLE "_Post_tags" (
"A" TEXT NOT NULL,
"B" TEXT NOT NULL,
FOREIGN KEY ("A") REFERENCES "Post" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY ("B") REFERENCES "Tag" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- CreateIndex
CREATE UNIQUE INDEX "_Post_tags_AB_unique" ON "_Post_tags"("A", "B");
-- CreateIndex
CREATE INDEX "_Post_tags_B_index" ON "_Post_tags"("B");
You need to modify it so that it looks like this with the old and new table names for your schema substituted:
ALTER TABLE "_Post_tags_Tag_posts" RENAME TO "_Post_tags";
DROP INDEX "_Post_tags_Tag_posts_AB_unique";
DROP INDEX "_Post_tags_Tag_posts_B_index";
CREATE UNIQUE INDEX "_Post_tags_AB_unique" ON "_Post_tags"("A", "B");
CREATE INDEX "_Post_tags_B_index" ON "_Post_tags"("B");