视图
视图支持目前处于非常早期的 预览 功能阶段。您可以使用 view
关键字将视图添加到 Prisma 模式中,或者使用 db pull
内省数据库模式中的视图。您还不能使用 Prisma Migrate 和 db push
将模式中的视图应用到数据库中,除非使用 --create-only
标志手动将更改添加到迁移文件中。
有关此功能进度的更新,请关注 我们的 GitHub 问题。
数据库视图允许您命名和存储查询。在关系数据库中,视图是 存储的 SQL 查询,可能包含多个表中的列,或计算值(如聚合)。在 MongoDB 中,视图是可查询的对象,其内容由 其他集合上的聚合管道 定义。
views
预览功能允许您使用 view
关键字在 Prisma 模式中表示视图。要在 Prisma ORM 中使用视图,请按照以下步骤操作
- 启用
views
预览功能 - 在底层数据库中创建视图,可以直接创建或作为 Prisma Migrate 迁移文件的手动添加,或者使用现有的视图
- 在 Prisma 模式中表示视图
- 在 Prisma Client 中查询视图
启用 views
预览功能
视图支持目前处于早期预览阶段。要启用 views
预览功能,请将 views
功能标志添加到 Prisma 模式中 generator
块的 previewFeatures
字段中
generator client {
provider = "prisma-client-js"
previewFeatures = ["views"]
}
请在我们的专用 views
预览功能反馈问题 中留下有关此预览功能的反馈。
在底层数据库中创建视图
目前,您无法使用 Prisma Migrate 和 db push
将在 Prisma 模式中定义的视图应用到数据库中。相反,您必须首先在底层数据库中手动创建视图或 作为迁移的一部分 创建视图。
例如,以下 Prisma 模式包含一个 User
模型和一个相关的 Profile
模型
- 关系数据库
- 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
}
接下来,在底层数据库中获取一个 UserInfo
视图,该视图组合了 User
模型中的 email
和 name
字段以及 Profile
模型中的 bio
字段。
对于关系数据库,创建此视图的 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
关键字。
您可以使用以下方法在 Prisma 模式中表示上述示例中的 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
块包含两个主要部分
view
块定义- 视图的字段定义
这两个部分允许您在生成的 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。
如果您在数据库中定义了现有视图,内省 将自动在 Prisma 模式中生成表示这些视图的 view
块。
假设示例 UserInfo
视图存在于您的底层数据库中,运行以下命令将在您的 Prisma 模式中生成一个表示该视图的 view
块
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 中使用内省的视图,您需要选择和定义一个或多个字段作为唯一标识符。
在上述视图的情况下,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
目录
内省包含一个或多个现有视图的数据库,还将在您的 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 以与模型相同的方式处理视图。这意味着视图至少需要一个唯一标识符,可以使用以下任何一种表示
在关系数据库中,视图的唯一标识符可以定义为一个字段上的 @unique
属性,或多个字段上的 @@unique
属性。如果可能,最好使用 @unique
或 @@unique
约束而不是 @id
或 @@id
字段。
然而,在 MongoDB 中,唯一标识符必须是 @id
属性,该属性使用 @map("_id")
映射到基础数据库中的 _id
字段。
在上面的示例中,id
字段具有 @unique
属性。如果基础 User
表中的另一个列被定义为唯一可识别并在视图的查询结果中可用,则该列可以用作唯一标识符。
内省
目前,视图的内省仅适用于 PostgreSQL、MySQL、SQL Server 和 CockroachDB。如果您使用的是其他数据库提供程序,则必须手动添加视图。
这是一个临时的限制,对其他受支持的数据源提供程序的支持将扩展到内省。
在 Prisma Client 中查询视图
您可以像查询模型一样在 Prisma Client 中查询视图。例如,以下查询查找上面定义的 UserInfo
视图中所有名为 '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
反馈问题 中评论您的用例。
物化视图
某些数据库支持物化视图,例如 PostgreSQL、CockroachDB、MongoDB 和 SQL Server(在其中称为“索引视图”)。
物化视图会保留视图查询的结果以加快访问速度,并且仅按需更新它。
目前,Prisma ORM 不支持物化视图。但是,当您手动创建视图时,您也可以使用基础数据库中的相应命令创建物化视图。然后,您可以使用 Prisma Client 的 TypedSQL 功能 执行命令并手动刷新视图。
将来 Prisma Client 可能会支持将单个视图标记为物化,并添加 Prisma Client 方法来刷新物化视图。请在我们的 views
反馈问题 中评论您的用例。