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

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ランタイム間の互換性を向上させるため、Node.js固有のAPIから標準JavaScriptへと徐々に移行しています。

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への変換

Buffer.fromを使用してUint8ArrayからBufferを作成できます。

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を削除し、エラーコード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

このリリースでは、asyncawait、およびusingをモデル名として使用できなくなります。

一般提供(GA)に昇格されたプレビュー機能

このリリースでは、いくつかのプレビュー機能を一般提供(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"]
}
© . All rights reserved.