Prisma ORM 6 へのアップグレード
Prisma ORM v6 では、以前のバージョンの Prisma ORM からアップグレードする際に、多くの破壊的変更が導入されています。このガイドでは、このアップグレードがアプリケーションにどのような影響を与える可能性があるかを説明し、変更に対処する方法について説明します。
prisma
および @prisma/client
パッケージを v6 にアップグレードする
以前のバージョンから Prisma ORM v6 にアップグレードするには、prisma
と @prisma/client
の両方のパッケージを更新する必要があります。
- npm
- yarn
- pnpm
- bun
npm install @prisma/client@6
npm install -D prisma@6
yarn up prisma@6 @prisma/client@6
pnpm upgrade prisma@6 @prisma/client@6
bun add @prisma/client@6
bun add prisma@6 --dev
アップグレードする前に、以下の各破壊的変更を確認して、アップグレードがアプリケーションにどのように影響するかを確認してください。
破壊的変更
このセクションでは、Prisma ORM v6 の破壊的変更の概要を示します。
最小サポート Node.js バージョン
Prisma ORM v6 で新たにサポートされる最小 Node.js バージョンは次のとおりです。
- Node.js 18 の場合、最小サポートバージョンは 18.18.0 です。
- Node.js 20 の場合、最小サポートバージョンは 20.9.0 です。
- Node.js 22 の場合、最小サポートバージョンは 22.11.0 です。
Node.js 16、17、19、および 21 は公式にはサポートされていません。
最小サポート TypeScript バージョン
Prisma ORM v6 で新たにサポートされる最小 TypeScript バージョンは 5.1.0 です。
このスキーマ変更は PostgreSQL にのみ適用されます。
CockroachDB を使用している場合、何もする必要はありません。暗黙的な多対多リレーションシップのスキーマは変更されません。
PostgreSQL での暗黙的な多対多リレーションシップのスキーマ変更
PostgreSQL を使用していて、Prisma スキーマで暗黙的な多対多リレーションシップを定義している場合、Prisma ORM はバックグラウンドでリレーションテーブルを管理します。このリレーションテーブルには、このリレーションの一部であるモデルのテーブルを表す A
列と B
列があります。
以前のバージョンの Prisma ORM では、これらの 2 つの列にユニークインデックスを作成していました。Prisma v6 では、デフォルトのレプリカアイデンティティの動作を簡素化するために、このユニークインデックスが主キーに変更されています。
例を展開
例として、Post
モデルと Tag
モデル間の暗黙的な多対多リレーションシップを持つ次の Prisma スキーマを考えてみましょう。
model Post {
id Int @id @default(autoincrement())
title String
categories Tag[]
}
model Tag {
id Int @id @default(autoincrement())
name String
posts Post[]
}
この場合、Prisma ORM はバックグラウンドで次のリレーションテーブルを管理します。
-- CreateTable
CREATE TABLE "_PostToTag" (
"A" INTEGER NOT NULL,
"B" INTEGER NOT NULL
);
-- CreateIndex
CREATE UNIQUE INDEX "_PostToTag_AB_unique" ON "_PostToTag"("A", "B");
-- CreateIndex
CREATE INDEX "_PostToTag_B_index" ON "_PostToTag"("B");
-- AddForeignKey
ALTER TABLE "_PostToTag" ADD CONSTRAINT "_PostToTag_A_fkey" FOREIGN KEY ("A") REFERENCES "Post"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_PostToTag" ADD CONSTRAINT "_PostToTag_B_fkey" FOREIGN KEY ("B") REFERENCES "Tag"("id") ON DELETE CASCADE ON UPDATE CASCADE;
Prisma v6 では、UNIQUE INDEX
が PRIMARY KEY
に変更されます。
-- CreateTable
CREATE TABLE "_PostToTag" (
"A" INTEGER NOT NULL,
"B" INTEGER NOT NULL,
CONSTRAINT "_PostToTag_AB_pkey" PRIMARY KEY ("A","B")
);
-- CreateIndex
CREATE INDEX "_PostToTag_B_index" ON "_PostToTag"("B");
-- AddForeignKey
ALTER TABLE "_PostToTag" ADD CONSTRAINT "_PostToTag_A_fkey" FOREIGN KEY ("A") REFERENCES "Post"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_PostToTag" ADD CONSTRAINT "_PostToTag_B_fkey" FOREIGN KEY ("B") REFERENCES "Tag"("id") ON DELETE CASCADE ON UPDATE CASCADE;
Prisma スキーマで暗黙的な多対多リレーションシップを定義している場合、次に作成するマイグレーションには、これらのリレーションシップに属するすべてのリレーションテーブルに対する ALTER TABLE
ステートメントが含まれます。これらは次のようになります。
-- AlterTable
ALTER TABLE "_PostToTag" ADD CONSTRAINT "_PostToTag_AB_pkey" PRIMARY KEY ("A", "B");
-- DropIndex
DROP INDEX "_PostToTag_AB_unique";
これらのスキーマ変更を分離するため(および次のマイグレーションにバンドルされないようにするため)、**Prisma v6 にアップグレードした直後に新しいマイグレーションを作成することをお勧めします**。
npx prisma migrate dev --name upgrade-to-v6
そうすることで、このスキーマ変更を処理し、それ以外の場合はマイグレーション履歴をクリーンに保つ、単一の専用マイグレーションを作成できます。
PostgreSQL での全文検索
fullTextSearch
プレビュー機能は、MySQL に対してのみ一般提供 (GA) に昇格しました。つまり、PostgreSQL を使用していて、現在このプレビュー機能を使用している場合は、新しいfullTextSearchPostgres
プレビュー機能を使用する必要があります。
変更前
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
previewFeatures = ["fullTextSearch"]
}
変更後
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
previewFeatures = ["fullTextSearchPostgres"]
}
Buffer
の使用
Prisma と最新の JavaScript ランタイム間の互換性を向上させるために、標準の JavaScript を優先して、Node.js 固有の API から徐々に移行しています。
Prisma v6 では、Bytes
型のフィールドを表すために、Buffer
の使用をUint8Array
に置き換えます。Buffer
型のすべての出現箇所を新しい Uint8Array
に置き換えてください。
Buffer
と Uint8Array
間の変換方法を表示するには展開してください。
Buffer
から Uint8Array
への変換
Buffer
インスタンスを Uint8Array
として直接使用できます。
const buffer: Buffer = Buffer.from([1, 2, 3, 4]);
const uint8Array: Uint8Array = buffer; // No conversion needed
Uint8Array
から Buffer
への変換
Uint8Array
から Buffer
を作成するには、Buffer.from
を使用します。
const uint8Array: Uint8Array = new Uint8Array([1, 2, 3, 4]);
const buffer: Buffer = Buffer.from(uint8Array.buffer);
変更前
- コード
- Prisma スキーマ
import { PrismaClient } from '@prisma/client'
async function main() {
const prisma = new PrismaClient()
await prisma.user.deleteMany()
const bytesCreated = await prisma.user.create({
data: {
bytes: Buffer.from([1, 2, 3, 4]),
},
})
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
// `bytesCreated` used to have type: {
// bytes: Buffer
// id: number
// }
for (const bytesFound of await prisma.user.findMany()) {
bytesFound.bytes // Buffer [ 1, 2, 3, 4 ]
}
}
main()
model User {
id Int @id @default(autoincrement())
bytes Bytes
}
変更後
- コード
- Prisma スキーマ
import { PrismaClient } from '@prisma/client'
async function main() {
const prisma = new PrismaClient()
await prisma.user.deleteMany()
const bytesCreated = await prisma.user.create({
data: {
bytes: Uint8Array.from([1, 2, 3, 4]),
},
})
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
// `bytesCreated` now has type: {
// bytes: Uint8Array
// id: number
// }
for (const bytesFound of await prisma.user.findMany()) {
bytesFound.bytes // Uint8Array [ 1, 2, 3, 4 ]
}
}
main()
model User {
id Int @id @default(autoincrement())
bytes Bytes
}
NotFoundError
の削除
Prisma v6 では、findUniqueOrThrow()
および findFirstOrThrow()
で NotFoundError
を削除し、エラーコード P2025
の PrismaClientKnownRequestError
を使用するように変更しました。コード内で NotFoundError
インスタンスのキャッチに依存している場合は、それに応じてコードを調整する必要があります。
変更前
import { PrismaClient, NotFoundError } from '@prisma/client';
// inside an `async` function
try {
const user = await prisma.user.findUniqueOrThrow({
where: { id: 42 },
});
console.log(user);
} catch (error) {
if (error instanceof NotFoundError) {
console.error("User not found!");
}
else {
console.error("Unexpected error:", error);
}
}
変更後
import { PrismaClient, Prisma } from '@prisma/client';
// inside an `async` function
try {
const user = await prisma.user.findUniqueOrThrow({
where: { id: 42 },
});
console.log(user);
} catch (error) {
if (
error instanceof Prisma.PrismaClientKnownRequestError &&
error.code === 'P2025' // Specific code for "record not found"
) {
console.error("User not found!");
}
else {
console.error("Unexpected error:", error);
}
}
モデル名として使用できなくなった新しいキーワード: async
、await
、using
このリリースでは、async
、await
、using
をモデル名として使用できなくなりました。
一般提供 (GA) に昇格したプレビュー機能
このリリースでは、多数のプレビュー機能を一般提供に昇格します。
fullTextIndex
アプリで全文インデックス機能を使用している場合は、Prisma スキーマの previewFeatures
から fullTextIndex
を削除できるようになりました。
generator client {
provider = "prisma-client-js"
previewFeatures = ["fullTextIndex"]
}
fullTextSearch
アプリでMySQL で全文検索機能を使用している場合は、Prisma スキーマの previewFeatures
から fullTextSearch
を削除できるようになりました。
generator client {
provider = "prisma-client-js"
previewFeatures = ["fullTextSearch"]
}
PostgreSQL で使用している場合は、機能フラグの名前を fullTextSearchPostgres
に更新する必要があります。
generator client {
provider = "prisma-client-js"
previewFeatures = ["fullTextSearchPostgres"]
}