视图
目前,对视图的支持是一个非常早期的 预览 功能。您可以使用 view
关键字将视图添加到 Prisma 架构中,或者使用 db pull
内省数据库架构中的视图。您还无法将架构中的视图应用于数据库,使用 Prisma Migrate 和 db push
,除非使用 --create-only
标志手动将更改添加到迁移文件中。
有关此功能进度的更新,请关注 我们的 GitHub 问题.
数据库视图允许您命名和存储查询。在关系数据库中,视图是 存储的 SQL 查询,可能包含多个表中的列,或计算的值,如聚合。在 MongoDB 中,视图是可查询的对象,其内容由 其他集合上的聚合管道 定义。
views
预览功能允许您使用 view
关键字在 Prisma 架构中表示视图。要在 Prisma ORM 中使用视图,请按照以下步骤操作
启用 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 客户端中定义视图的名称,以及视图查询结果中存在的列。
定义 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 客户端中使用内省的视图,您需要选择并定义一个或多个字段作为唯一的标识符。
在上面的视图情况下,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
视图中所有 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
反馈问题 中评论您的用例。
物化视图
一些数据库支持物化视图,例如 PostgreSQL、CockroachDB、MongoDB 和 SQL Server(称为“索引视图”)。
物化视图持久化视图查询的结果,以便更快地访问,并且仅在需要时更新。
目前,Prisma ORM 不支持物化视图。但是,当您 手动创建视图 时,您也可以使用底层数据库中的相应命令创建物化视图。然后,您可以使用 Prisma Client 的 TypedSQL 功能 来执行命令并手动刷新视图。
将来,Prisma Client 可能会支持将单个视图标记为物化,并添加一个 Prisma Client 方法来刷新物化视图。请在我们的 views
反馈问题 中评论您的用例。