メインコンテンツにスキップ

Prisma ORM 6 へのアップグレード

Prisma ORM v6 では、以前のバージョンの Prisma ORM からアップグレードする際に、多くの破壊的変更が導入されています。このガイドでは、このアップグレードがアプリケーションにどのような影響を与える可能性があるかを説明し、変更に対処する方法について説明します。

prisma および @prisma/client パッケージを v6 にアップグレードする

以前のバージョンから Prisma ORM v6 にアップグレードするには、prisma@prisma/client の両方のパッケージを更新する必要があります。

npm install @prisma/client@6
npm install -D prisma@6
危険

アップグレードする前に、以下の各破壊的変更を確認して、アップグレードがアプリケーションにどのように影響するかを確認してください。

破壊的変更

このセクションでは、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 INDEXPRIMARY 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 プレビュー機能を使用する必要があります。

変更前

schema.prisma
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}

generator client {
provider = "prisma-client-js"
previewFeatures = ["fullTextSearch"]
}

変更後

schema.prisma
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 に置き換えてください。

BufferUint8Array 間の変換方法を表示するには展開してください。

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);

変更前

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()

変更後

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()

NotFoundError の削除

Prisma v6 では、findUniqueOrThrow() および findFirstOrThrow()NotFoundError を削除し、エラーコード P2025PrismaClientKnownRequestError を使用するように変更しました。コード内で 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);
}
}

モデル名として使用できなくなった新しいキーワード: asyncawaitusing

このリリースでは、asyncawaitusing をモデル名として使用できなくなりました。

一般提供 (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"]
}