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

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

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

破壊的な変更

このセクションでは、Prisma ORM 4における破壊的な変更の概要を説明します。これらの変更は、PrismaスキーマとPrisma Clientの両方に影響する一般的な変更スキーマの変更、およびクライアントの変更に分類されています。

まずPrismaスキーマの検証エラーに対処し、次にデータベースをpullして新しいPrismaスキーマの機能を反映させ、最後にPrisma Clientの型エラーを修正し、テストスイートを実行して検証することを推奨します。

Prismaスキーマをアップグレードする

  1. 変更の一覧を注意深く確認し、破壊的な変更の影響を受けるかどうかを確認してください。
  2. Prismaスキーマの検証エラーを確認してください(npx prisma validate、またはPrisma VS Code拡張機能を使用)。
    1. 検証エラーがない場合は、ステップ3に進んでください。
    2. 検証エラーがある場合
      1. 検証エラーを以下のリストの変更点にマッピングして、どの変更がPrismaスキーマを無効にしたのかを理解し、アップグレード方法に関するリンクされた手順をお読みください。以下のいずれかに起因する可能性があります。
  3. Prismaスキーマが有効になるまで繰り返します。
  4. npx prisma db pullを実行して、Prismaスキーマをすべての新機能(例:extendedIndexes)にアップグレードします。
  5. Prismaスキーマの変更を確認し、有効性を検証します。
  6. Prisma Clientのステップに進みます。

Prisma Clientの使用をアップグレードする

  1. 変更の一覧を注意深く確認し、破壊的な変更の影響を受けるかどうかを確認してください。
    1. はいの場合は、詳細なアップグレード手順をお読みください。
    2. いいえの場合は、2に進んでください。
  2. Prisma Clientの一部のAPI変更はランタイムの動作に影響を与えるため、テストスイートを実行してください。

Prisma ORM 4をお楽しみください!

一般的な変更

このセクションでは、PrismaスキーマとPrisma Clientの両方に影響する変更について説明します。

Node.jsの最小バージョン変更

Prisma ORMバージョン4.0.0以降では、サポートするNode.jsの最小バージョンは14.17.xです。以前のバージョンのNode.jsを使用している場合は、アップデートする必要があります。

すべての最小バージョン要件については、システム要件を参照してください。

スキーマの変更

このセクションでは、Prismaスキーマに影響する変更について説明します。

インデックス構成

Prisma ORM 4では、extendedIndexesプレビュー機能が一般公開されます。これには、次のインデックス構成オプションが含まれます

  • MySQLのインデックス、ユニーク制約、および主キー制約の長さ構成(バージョン3.5.0以降でプレビュー)
  • インデックス、ユニーク制約、および主キー制約のソート順構成(バージョン3.5.0以降でプレビュー)
  • PostgreSQLの新しいインデックスタイプ:Hash(バージョン3.6.0以降でプレビュー)およびGIN、GiST、SP-GiST、BRIN(バージョン3.14.0以降でプレビュー)
  • SQL Serverのインデックスクラスタリング(バージョン3.13.0以降でプレビュー)

これらの機能の詳細については、インデックス構成に関するドキュメントを参照してください。

アップグレードパス

これらはすべて、以前にデータベースレベルでこれらのプロパティを構成していた場合、破壊的な変更となる可能性があります。この場合は、次の手順を実行する必要があります

  1. これらの手順に従って、新しいPrisma ORM 4パッケージにアップグレードする
  2. その後、npx prisma db pullを実行して、既存のインデックスと制約の構成を取得します。これは、npx prisma db pushまたはnpx prisma migrate devコマンドを実行する前に行う必要があります。そうしないと、データベースで定義されているが、以前はPrismaスキーマで表現されていなかった構成が失われる可能性があります。

詳細については、インデックス構成ドキュメントの「以前のバージョンからのアップグレード」セクションを参照してください。

スカラーリストのデフォルト

スカラーリストをサポートするデータベースコネクタ(PostgreSQL、CockroachDB、MongoDB)の場合、Prisma ORM 4では、@default属性を使用してPrismaスキーマでデフォルト値を設定する機能が導入されています

model User {
id Int @id @default(autoincrement())
posts Post[]
favoriteColors String[] @default(["red", "yellow", "purple"])
}
アップグレードパス

これは、以前にデータベースレベルでスカラーリストのデフォルトを定義していた場合、破壊的な変更となります。この場合は、次の手順を実行する必要があります

  1. これらの手順に従って、新しいPrisma ORM 4パッケージにアップグレードする
  2. その後、npx prisma db pullを実行して、既存のインデックスと制約の構成を取得します。これは、npx prisma db pushまたはnpx prisma migrate devコマンドを実行する前に行う必要があります。そうしないと、データベースで定義されているが、以前はPrismaスキーマで表現されていなかったデフォルトが失われます。

1対1リレーションシップの明示的な@unique制約

Prisma ORM 4で1対1リレーションシップを使用する場合、リレーションスカラーフィールドに@unique属性を明示的に追加する必要があります。たとえば、UserモデルとProfileモデル間のこの1対1リレーションシップの場合、profileIdフィールドに@unique属性を追加する必要があります

model User {
id Int @id @default(autoincrement())
profile Profile? @relation(fields: [profileId], references: [id])
profileId Int? @unique // <-- include this explicitly
}

model Profile {
id Int @id @default(autoincrement())
user User?
}
アップグレードパス

Prisma ORM 4にアップグレードした後、リレーションスカラーに@unique属性がない1対1リレーションシップは検証エラーをトリガーします。アップグレードするには、次の手順を実行する必要があります

  1. これらの手順に従って、新しいPrisma ORM 4パッケージにアップグレードする

  2. データモデルに明示的な@uniqueまたは@id属性を追加して、Prismaスキーマの検証エラーを手動で修正します。

  3. MongoDBの場合はprisma db push、MySQLの場合はprisma migrate devを使用して、変更をデータベースにプッシュします。

1対1および1対多リレーションシップでの@uniqueまたは@id属性の使用を強制(MySQLおよびMongoDB)

Prisma ORM 4で1対1および1対多リレーションシップを使用する場合、リレーションの単数側がレコードを1つしか持たないことを保証するために、リレーションフィールドに@unique属性を使用する必要があります。これは現在、MySQLおよびMongoDBで強制されており、他のコネクタと一致するようになります。@unique属性がない場合、検証エラーがトリガーされるようになります。

UserモデルとPostモデル間の1対多リレーションシップの次の例では、@unique属性をemailフィールドに追加する必要があります

model User {
id Int @id @default(autoincrement())
email String @unique // <-- we enforce this attribute
posts Post[]
}

model Post {
id Int @id @default(autoincrement())
authorEmail String
author User @relation(fields: [authorEmail], references: [email])
}

UserモデルとProfileモデル間の1対1リレーションシップの次の例では、@unique属性をemailフィールドに追加する必要があります

model User {
id Int @id @default(autoincrement())
email String @unique // <- we enforce this unique attribute
profile Profile @relation(fields: [profileId], references: [id])
profileId Int
}

model Profile {
id Int @id @default(autoincrement())
userEmail String? @unique
user User?
}
アップグレードパス

Prisma ORM 4にアップグレードした後、リレーションフィールドに@uniqueまたは@id属性がない1対1または1対多リレーションシップは検証エラーをトリガーします。アップグレードするには、次の手順を実行する必要があります

  1. これらの手順に従って、新しいPrisma ORM 4パッケージにアップグレードする
  2. Prismaスキーマの検証エラーを手動で修正します。または、最新のライブデータベースがある場合は、npx prisma db pullを実行すると、@unique属性が自動的に追加されます。

暗黙の多対多リレーションシップのreferences構文を禁止

Prisma ORM 4で暗黙の多対多リレーションシップを使用する場合、以前はオプションだったreferences引数を使用できなくなります。たとえば、次のリレーションシップは検証エラーをトリガーするようになります

schema.prisma
model Post {
id Int @id @default(autoincrement())
categories Category[] @relation("my-relation", references: [id]) // <-- validation error
}

model Category {
id Int @id @default(autoincrement())
posts Post[] @relation("my-relation", references: [id]) // <-- validation error
}

代わりに、次のように記述できます

schema.prisma
model Post {
id Int @id @default(autoincrement())
categories Category[] @relation("my-relation")
}

model Category {
id Int @id @default(autoincrement())
posts Post[] @relation("my-relation")
}

これは、referencesの唯一の有効な値がidであったため、この引数を削除することで、何を変更できるか、何を変更できないかをより明確にするためです。

アップグレードパス

Prisma ORM 4にアップグレードした後、references引数を持つ暗黙の多対多リレーションシップは検証エラーをトリガーします。アップグレードするには、次の手順を実行する必要があります

  1. これらの手順に従って、新しいPrisma ORM 4パッケージにアップグレードする
  2. Prismaスキーマの検証エラーを手動で修正します。または、最新のライブデータベースがある場合は、npx prisma db pullを実行すると、references引数が自動的に削除されます。

文字列リテラルの文法改善

Prismaスキーマの文字列リテラルは、JSONの文字列と同じルールに従う必要があります。これにより、主に一部の特殊文字のエスケープが変更されます。詳細については、JSON仕様またはJSONウェブサイトを参照してください。

アップグレードパス

これは、既存のスキーマの一部にとって破壊的な変更です。Prisma ORM 4にアップグレードした後、誤ってエスケープされた文字は検証エラーをトリガーします。アップグレードするには、次の手順を実行する必要があります

  1. これらの手順に従って、新しいPrisma ORM 4パッケージにアップグレードする
  2. Prismaスキーマの検証エラーを手動で修正します。

クライアントの変更

このセクションでは、Prisma Clientに影響する変更について説明します。

Rawクエリの型マッピング:スカラー値が正しいJavaScript型としてデシリアライズされるようになりました

バージョン3.14.xおよび3.15.xでは、rawクエリの型マッピングはプレビュー機能improvedQueryRawで使用可能でした。バージョン4.0.0では、rawクエリの型マッピングを一般公開しました。バージョン4.0.0以降でこの機能を使用するためにimprovedQueryRawを使用する必要はありません。

Rawクエリは、スカラー値を対応するJavaScript型にデシリアライズするようになりました。Prisma ORMは、Prismaスキーマ型からではなく、値自体から型を推測することに注意してください。

クエリとレスポンスの例

const res =
await prisma.$queryRaw`SELECT bigint, bytes, decimal, date FROM "Table";`
console.log(res) // [{ bigint: BigInt("123"), bytes: Buffer.from([1, 2]), decimal: new Prisma.Decimal("12.34"), date: Date("<some_date>") }]
アップグレードパス

バージョン4.0.0以降では、queryRawまたはqueryRawUnsafeによって返される一部のデータ型が次のように異なります

データ型バージョン4.0.0より前バージョン4.0.0以降
DateTimeStringとして返されるDateとして返される
NumericFloatとして返されるDecimalとして返される
BytesStringとして返されるBufferとして返される
Int64Integerとして返されるBigIntとして返される

queryRawまたはqueryRawUnsafeを使用して上記のデータ型を返す場合は、新しい型を処理するようにコードを変更する必要があります。

たとえば、DateTimeデータを返す場合は、次の点を考慮する必要があります

  • 返されたデータに対してDateTimeオブジェクトを手動でインスタンス化する必要はなくなりました。
  • コードが現在返されたStringデータを使用している場合は、DateTimeオブジェクトをStringに変換する必要があります。

上記の表の他のデータ型についても、同等のコード変更を行う必要があります。

Rawクエリマッピング:PostgreSQLの型キャスト

バージョン3.14.xおよび3.15.xでは、rawクエリの型マッピングはプレビュー機能improvedQueryRawで使用可能でした。バージョン4.0.0では、rawクエリの型マッピングを一般公開しました。バージョン4.0.0以降でこの機能を使用するためにimprovedQueryRawを使用する必要はありません。

バージョン4.0.0より前は、多くのPostgreSQLの型キャストが機能しませんでした。すべての型キャストが機能するように型強制ルールを厳格化しました。その結果、一部の暗黙的なキャストが失敗するようになりました。

アップグレードパス

$queryRawの使用を再テストして、rawクエリに渡す型がPostgreSQLが期待する型と一致することを確認することを推奨します。

たとえば、バージョン4.0.0では、次のクエリは失敗します

await prisma.$queryRaw`select length(${42});`
// ERROR: function length(integer) does not exist
// HINT: No function matches the given name and argument types. You might need to add explicit type casts.

これは、PostgreSQLのlength関数が入力としてtextを期待するためです。Prisma ORMは以前は42textに暗黙的に強制変換していましたが、バージョン4.0.0ではこれを行いません。これを修正するには、次のように42を明示的にtextにキャストします

await prisma.$queryRaw`select length(${42}::text);`

Rawクエリマッピング:PostgreSQLとJavaScriptの整数

バージョン3.14.xおよび3.15.xでは、rawクエリの型マッピングはプレビュー機能improvedQueryRawで使用可能でした。バージョン4.0.0では、rawクエリの型マッピングを一般公開しました。バージョン4.0.0以降でこの機能を使用するためにimprovedQueryRawを使用する必要はありません。

Prisma ORMはJavaScriptの整数をPostgreSQLにINT8として送信します。これは、INT4のみを入力として受け入れるユーザー定義関数と競合する可能性があります。

アップグレードパス

PostgreSQLデータベースで$queryRawまたはパラメーター化された$queryRawUnsafeクエリを使用する場合は、次のいずれかを実行してください

  • ユーザー定義関数の整数の入力型をINT8に更新するか、
  • クエリパラメーターの整数をINT4にキャストします。

DbNull、JsonNull、およびAnyNullがオブジェクトになりました

JavaScriptのnullはJSON列に対してあいまいであるため、Prisma ORMはDbNull、JsonNull、およびAnyNullを使用して、データベースのNULL値とJSONのnull値を区別します。バージョン4.0.0より前は、DbNull、JsonNull、およびAnyNullは文字列定数でした。バージョン4.0.0以降では、オブジェクトになります。

詳細については、null値によるフィルタリングを参照してください。

アップグレードパス
  1. これらの値をアドレス指定するためにリテラル文字列を使用する場合は、次の名前付き定数に置き換える必要があります

    • DbNull: Prisma.DbNullに置き換える
    • JsonNull: Prisma.JsonNullに置き換える
    • AnyNull: Prisma.AnyNullに置き換える

    これらの名前付き定数をすでに使用している場合は、何もする必要はありません。

  2. JSONフィールドの値としてPrisma.DbNullを渡すと型エラーが発生する場合、これはおそらくバージョン4.0.0より前に型がキャッチしていなかったコードのバグを示しています。DbNullを保存しようとしたフィールドは、スキーマでnull許容ではない可能性があります。その結果、リテラルDbNull文字列がNULLの代わりにデータベースに保存されました。

  3. MongoDBでPrisma.DbNullPrisma.JsonNull、またはPrisma.AnyNullを使用すると、型エラーまたはランタイム検証エラーが発生する可能性があります。これは決して有効ではありませんでしたが、Prisma ORM 4より前は暗黙的に受け入れられていました。データをレビューし、これらのフィールドをnullに変更する必要があります。

  4. Prisma ClientのJSON列に動的JSONを渡す場合(たとえば、prisma.findMany({where: { jsonColumn: someJson } }))、someJsonが文字列「DBNull」、「JsonNull」、または「AnyNull」でないことを確認する必要があります。これらの値のいずれかである場合、クエリはバージョン4.0.0で異なる結果を返します。

MongoDBの複合型のデフォルトフィールド

バージョン4.0.0以降では、次の条件がすべて満たされている場合に複合型でデータベース読み取りを実行すると、Prisma Clientは結果にデフォルト値を挿入します。

条件

  • 複合型のフィールドが必須であり、
  • このフィールドにデフォルト値があり、
  • このフィールドが返されたドキュメントに存在しない場合。

この動作は、モデルフィールドの動作と一致するようになりました。

詳細については、複合型の必須フィールドのデフォルト値を参照してください。

アップグレードパス

現在nullの戻り値に依存している場合は、Prisma ORM 4で返されるようになったデフォルト値を処理するようにコードをリファクタリングする必要があります。

SQLiteの大きな数値の丸め誤差

SQLiteはloosely-typedデータベースです。スキーマにInt型のフィールドがある場合、Prisma ORMは整数よりも大きい値を挿入することを防ぎます。ただし、データベースが直接大きな数値を受け入れることを防ぐものはありません。これらの手動で挿入された大きな数値は、クエリされたときに丸め誤差を引き起こします。

この問題を回避するために、Prisma ORMバージョン4.0.0以降では、データベースから出力される数値をチェックして、整数境界内に収まっていることを確認します。数値が収まらない場合、Prisma ORMは次のようなP2023エラーをスローします

Inconsistent column data: Conversion failed:
Value 9223372036854775807 does not fit in an INT column,
try migrating the 'int' column type to BIGINT
アップグレードパス

Prisma ORMをSQLiteと組み合わせて使用する場合は、Intフィールドをクエリするコードを見つけ、返される可能性のあるP2023エラーを処理することを確認する必要があります。

Prisma ORMはPrisma.dmmf.schemaを生成されたPrisma Clientにエクスポートしなくなりました

バージョン4.0.0以降では、Prisma ORMはPrisma.dmmf.schemaを生成されたPrisma Clientにエクスポートしなくなりました。これにより、生成されたPrisma Clientが大幅に効率的になり、Jestでのメモリリークも回避されます。

注意

  • この変更は、Prisma ORMがジェネレーターに渡すDMMFには影響しません。
  • @prisma/internalsgetDmmf()を使用して、schemaプロパティにアクセスできます。
  • Prisma.dmmf.datamodelは引き続き生成されたPrisma Clientにエクスポートします。

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

以前のバージョンからPrisma ORM 4にアップグレードするには、prisma@prisma/clientの両方のパッケージを更新する必要があります。prisma@prisma/clientの両方のパッケージは、バージョン番号にキャレット^を付けてインストールされます。これにより、破壊的な変更から保護するために、新しいマイナーバージョンへのアップグレードは許可されますが、メジャーバージョンへのアップグレードは許可されません。

キャレット^を無視してメジャーバージョン間でアップグレードするには、npmまたはyarnでアップグレードするときに@4タグを使用できます

危険

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

npm install prisma@4 @prisma/client@4

ビデオガイド

アップグレードプロセスのビデオウォークスルーとアップグレードシナリオの例については、Prisma ORM 4へのアップグレードに関する録画されたライブストリームをご覧ください