ビュー
ビューのサポートは現在、非常に初期のプレビュー機能です。view
キーワードを使用してビューをPrismaスキーマに追加したり、db pull
でデータベーススキーマのビューをイントロスペクトしたりできます。--create-only
フラグを使用して変更を移行ファイルに手動で追加しない限り、Prisma Migrateとdb push
を使用してスキーマ内のビューをデータベースに適用することはまだできません。
この機能の進捗状況の更新については、GitHub issueをフォローしてください。
データベースビューを使用すると、クエリに名前を付けて保存できます。リレーショナルデータベースでは、ビューは保存されたSQLクエリであり、複数のテーブルの列や、集計などの計算値を含めることができます。MongoDBでは、ビューはクエリ可能なオブジェクトであり、その内容は他のコレクションの集計パイプラインによって定義されます。
views
プレビュー機能を使用すると、view
キーワードを使用してPrismaスキーマでビューを表すことができます。Prisma ORMでビューを使用するには、次の手順に従ってください。
views
プレビュー機能を有効にする- 基盤となるデータベースにビューを作成する、直接作成するか、Prisma Migrate移行ファイルへの手動追加として作成するか、既存のビューを使用する
- Prismaスキーマでビューを表す
- Prisma Clientでビューをクエリする
views
プレビュー機能を有効にする
ビューのサポートは現在、初期プレビュー段階です。views
プレビュー機能を有効にするには、Prismaスキーマのgenerator
ブロックのpreviewFeatures
フィールドにviews
フィーチャーフラグを追加します。
generator client {
provider = "prisma-client-js"
previewFeatures = ["views"]
}
このプレビュー機能に関するフィードバックは、専用のviews
のプレビュー機能フィードバックissueに残してください。
基盤となるデータベースにビューを作成する
現在、Prisma Migrateとdb push
を使用してPrismaスキーマで定義したビューをデータベースに適用することはできません。代わりに、まず基盤となるデータベースにビューを手動で作成するか、移行の一部として作成する必要があります。
例として、User
モデルと関連するProfile
モデルを含む次のPrismaスキーマを見てみましょう。
- リレーショナルデータベース
- MongoDB
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
profile Profile?
}
model Profile {
id Int @id @default(autoincrement())
bio String
user User @relation(fields: [userId], references: [id])
userId Int @unique
}
model User {
id String @id @default(auto()) @map("_id") @db.ObjectId
email String @unique
name String?
profile Profile?
}
model Profile {
id String @id @default(auto()) @map("_id") @db.ObjectId
bio String
User User @relation(fields: [userId], references: [id])
userId String @unique @db.ObjectId
}
次に、User
モデルのemail
フィールドとname
フィールド、およびProfile
モデルのbio
フィールドを組み合わせた基盤となるデータベースのUserInfo
ビューを見てみましょう。
リレーショナルデータベースの場合、このビューを作成するSQLステートメントは次のとおりです。
CREATE VIEW "UserInfo" AS
SELECT u.id, email, name, bio
FROM "User" u
LEFT JOIN "Profile" p ON u.id = p."userId";
MongoDBの場合、次のコマンドを使用してビューを作成することができます。
db.createView('UserInfo', 'User', [
{
$lookup: {
from: 'Profile',
localField: '_id',
foreignField: 'userId',
as: 'ProfileData',
},
},
{
$project: {
_id: 1,
email: 1,
name: 1,
bio: '$ProfileData.bio',
},
},
{ $unwind: '$bio' },
])
Prisma Migrateとdb push
でビューを使用する
Prisma Migrateまたはdb push
を使用してPrismaスキーマに変更を適用する場合、Prisma ORMはビューに関連するSQLを作成または実行しません。
移行にビューを含めるには、migrate dev --create-only
を実行し、ビューのSQLを移行ファイルに手動で追加します。または、データベースでビューを手動で作成することもできます。
Prismaスキーマにビューを追加する
Prismaスキーマにビューを追加するには、view
キーワードを使用します。
上記の例のUserInfo
ビューは、Prismaスキーマで次のように表すことができます。
- リレーショナルデータベース
- MongoDB
view UserInfo {
id Int @unique
email String
name String
bio String
}
view UserInfo {
id String @id @default(auto()) @map("_id") @db.ObjectId
email String
name String
bio String
}
手書き
view
ブロックは、主に次の2つの部分で構成されています。
view
ブロック定義- ビューのフィールド定義
これら2つの部分を使用すると、生成されたPrisma Clientのビューの名前と、ビューのクエリ結果に存在する列を定義できます。
view
ブロックを定義する
上記の例のUserInfo
ビューを定義するには、まずview
キーワードを使用して、UserInfo
という名前のview
ブロックをスキーマで定義します。
view UserInfo {
// Fields
}
フィールドを定義する
ビューのプロパティはフィールドと呼ばれ、次の要素で構成されます。
- フィールド名
- フィールドタイプ
UserInfo
の例のビューのフィールドは、次のように定義できます。
- リレーショナルデータベース
- MongoDB
view UserInfo {
id Int @unique
email String
name String
bio String
}
view UserInfo {
id String @id @default(auto()) @map("_id") @db.ObjectId
email String
name String
bio String
}
view
ブロックの各フィールドは、基盤となるデータベースのビューのクエリ結果の列を表します。
イントロスペクションを使用する
現在、PostgreSQL、MySQL、SQL Server、CockroachDBでのみ利用可能です。
データベースに既存のビューがある場合、イントロスペクションは、それらのビューを表すview
ブロックをPrismaスキーマに自動的に生成します。
例のUserInfo
ビューが基盤となるデータベースに存在すると仮定すると、次のコマンドを実行すると、そのビューを表すview
ブロックがPrismaスキーマに生成されます。
npx prisma db pull
結果のview
ブロックは、次のように定義されます。
/// The underlying view does not contain a valid unique identifier and can therefore currently not be handled by Prisma Client.
view UserInfo {
id Int?
email String?
name String?
bio String?
@@ignore
}
view
ブロックは、一意の識別子が定義されていないため(現在はビューのプレビュー機能の制限事項です)、最初は@@ignore
属性で生成されます。
当面の間、db pull
はPostgreSQL、MySQL、SQL Server、またはCockroachDBを使用している場合にのみスキーマ内のビューをイントロスペクトすることに注意してください。このワークフローのサポートは、他のデータベースプロバイダーにも拡張される予定です。
イントロスペクトされたビューに一意の識別子を追加する
イントロスペクトされたビューをPrisma Clientで使用できるようにするには、フィールドの1つまたは複数を選択して一意の識別子として定義する必要があります。
上記のビューの場合、id
列は基盤となるUser
テーブルの一意に識別可能なフィールドを参照しているため、そのフィールドをview
ブロック内の一意に識別可能なフィールドとしても使用できます。
このview
ブロックを有効にするには、次の操作を行う必要があります。
id
フィールドからオプションフラグ?
を削除する@unique
属性をid
フィールドに追加する@@ignore
属性を削除する- 無効なビューに関する生成されたコメント警告を削除する
/// The underlying view does not contain a valid unique identifier and can therefore currently not be handled by Prisma Client.
view UserInfo {
id Int?
id Int @unique
email String?
name String?
bio String?
@@ignore
}
データベースを再イントロスペクトすると、ビュー定義へのカスタム変更はすべて保持されます。
views
ディレクトリ
1つ以上の既存のビューを持つデータベースのイントロスペクションでは、prisma
ディレクトリ内に新しいviews
ディレクトリも作成されます(Prismaバージョン4.12.0以降)。このディレクトリには、データベースのスキーマの名前が付けられたサブディレクトリが含まれており、そのスキーマでイントロスペクトされた各ビューの.sql
ファイルが含まれています。各ファイルは個々のビューにちなんで名付けられ、関連するビューが定義するクエリが含まれます。
たとえば、上記のモデルを使用してデフォルトのpublic
スキーマを持つデータベースをイントロスペクトした後、次の内容でprisma/views/public/UserInfo.sql
ファイルが作成されていることがわかります。
SELECT
u.id,
u.email,
u.name,
p.bio
FROM
(
"User" u
LEFT JOIN "Profile" p ON ((u.id = p."userId"))
);
制限事項
一意の識別子
現在、Prisma ORMはビューをモデルと同じように扱います。これは、ビューには少なくとも1つ一意の識別子が必要であることを意味します。これは、次のいずれかで表すことができます。
リレーショナルデータベースでは、ビューの一意の識別子は、1つのフィールドの@unique
属性として、または複数のフィールドの@@unique
属性として定義できます。可能な場合は、@id
または@@id
フィールドよりも@unique
または@@unique
制約を使用することをお勧めします。
ただし、MongoDBでは、一意の識別子は、基盤となるデータベースの_id
フィールドに@map("_id")
でマッピングする@id
属性である必要があります。
上記の例では、id
フィールドに@unique
属性があります。基盤となるUser
テーブルの別の列が一意に識別可能として定義され、ビューのクエリ結果で利用可能になった場合、その列を一意の識別子として代わりに使用できた可能性があります。
イントロスペクション
現在、ビューのイントロスペクションは、PostgreSQL、MySQL、SQL Server、およびCockroachDBでのみ利用可能です。別のデータベースプロバイダーを使用している場合は、ビューを手動で追加する必要があります。
これは一時的な制限であり、イントロスペクションのサポートは、サポートされている他のデータソースプロバイダーにも拡張される予定です。
Prisma Clientでビューをクエリする
モデルをクエリするのと同じ方法で、Prisma Clientでビューをクエリできます。たとえば、次のクエリは、上記で定義したUserInfo
ビューでname
が'Alice'
のすべてのユーザーを検索します。
const userinfo = await prisma.userInfo.findMany({
where: {
name: 'Alice',
},
})
現在、Prisma Clientでは、基盤となるデータベースが許可している場合、追加の検証なしでビューを更新できます。
特殊なタイプのビュー
このセクションでは、データベースで更新可能なビューとマテリアライズドビューをPrisma ORMで使用する方法について説明します。
更新可能なビュー
一部のデータベースは更新可能なビューをサポートしています(例:PostgreSQL、MySQL、およびSQL Server)。更新可能なビューを使用すると、エントリの作成、更新、または削除が可能です。
現在、Prisma ORMはすべてのview
を更新可能なビューとして扱います。基盤となるデータベースがビューに対してこの機能をサポートしている場合、操作は成功するはずです。ビューが更新可能としてマークされていない場合、データベースはエラーを返し、Prisma Clientはこのエラーをスローします。
将来、Prisma Clientは個々のビューを更新可能または更新不可としてマークすることをサポートする可能性があります。ユースケースについて、views
フィードバックissueにコメントしてください。
マテリアライズドビュー
一部のデータベースはマテリアライズドビューをサポートしています。例:PostgreSQL、CockroachDB、MongoDB、およびSQL Server(「インデックス付きビュー」と呼ばれます)。
マテリアライズドビューは、高速アクセスを実現するためにビュークエリの結果を永続化し、オンデマンドでのみ更新します。
現在、Prisma ORMはマテリアライズドビューをサポートしていません。ただし、ビューを手動で作成する場合、基盤となるデータベースの対応するコマンドを使用してマテリアライズドビューを作成することもできます。その後、Prisma ClientのTypedSQL機能を使用してコマンドを実行し、ビューを手動で更新できます。
将来、Prisma Clientは個々のビューをマテリアライズドとしてマークし、マテリアライズドビューを更新するためのPrisma Clientメソッドを追加する可能性があります。ユースケースについて、views
フィードバックissueにコメントしてください。