視圖
目前對視圖的支援仍處於非常早期的預覽功能階段。您可以使用 view
關鍵字將視圖新增至您的 Prisma schema,或使用 db pull
在您的資料庫 schema 中內省視圖。除非使用 --create-only
標記手動將變更新增至您的遷移檔案,否則您尚無法使用 Prisma Migrate 和 db push
將 schema 中的視圖套用至您的資料庫。
如需此功能進度的更新,請追蹤我們的 GitHub issue。
資料庫視圖允許您命名和儲存查詢。在關聯式資料庫中,視圖是儲存的 SQL 查詢,可能包含多個表格中的欄位,或計算值,例如彙總。在 MongoDB 中,視圖是可查詢的物件,其內容由其他集合上的聚合管道定義。
views
預覽功能允許您使用 view
關鍵字在您的 Prisma schema 中表示視圖。若要在 Prisma ORM 中使用視圖,請依照下列步驟操作
- 啟用
views
預覽功能 - 在底層資料庫中建立視圖,可以直接建立,也可以作為手動新增至 Prisma Migrate 遷移檔案的一部分,或使用現有的視圖
- 在您的 Prisma schema 中表示視圖
- 在 Prisma Client 中查詢視圖
啟用 views
預覽功能
目前對視圖的支援處於早期預覽階段。若要啟用 views
預覽功能,請將 views
功能標記新增至您 Prisma Schema 中 generator
區塊的 previewFeatures
欄位
generator client {
provider = "prisma-client-js"
previewFeatures = ["views"]
}
請在我們專門的 views
預覽功能回饋 issue 中留下關於此預覽功能的意見回饋。
在底層資料庫中建立視圖
目前,您無法使用 Prisma Migrate 和 db push
將您在 Prisma schema 中定義的視圖套用至您的資料庫。相反地,您必須先在底層資料庫中建立視圖,可以手動建立,也可以作為遷移的一部分建立。
例如,以下列具有 User
模型和相關 Profile
模型的 Prisma schema 為例
- 關聯式資料庫
- 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 schema,Prisma ORM 不會建立或執行任何與視圖相關的 SQL。
若要在遷移中加入視圖,請執行 migrate dev --create-only
,然後手動將視圖的 SQL 新增至您的遷移檔案。或者,您可以手動在資料庫中建立視圖。
將視圖新增至您的 Prisma schema
若要將視圖新增至您的 Prisma schema,請使用 view
關鍵字。
您可以將上述範例中的 UserInfo
視圖表示為如下的 Prisma schema
- 關聯式資料庫
- 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
關鍵字在您的 schema 中定義一個名為 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 schema 中產生代表這些視圖的 view
區塊。
假設範例 UserInfo
視圖存在於您的底層資料庫中,執行以下命令將在您的 Prisma schema 中產生一個代表該視圖的 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 時才會內省您 schema 中的視圖。此工作流程的支援將擴展到其他資料庫供應商。
將唯一識別符新增至內省的視圖
為了能夠在 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 開始)。此目錄將包含一個以您的資料庫 schema 命名的子目錄,其中包含每個在該 schema 中內省的視圖的 .sql
檔案。每個檔案將以個別視圖命名,並將包含相關視圖定義的查詢。
例如,在使用上述模型內省具有預設 public
schema 的資料庫之後,您會發現已建立一個 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
回饋 issue 中評論您的使用案例。
具體化視圖
某些資料庫支援具體化視圖,例如 PostgreSQL、CockroachDB、MongoDB 和 SQL Server (在 SQL Server 中稱為「索引檢視表」)。
具體化視圖會持久儲存視圖查詢的結果以加快存取速度,並且僅在需要時更新。
目前,Prisma ORM 不支援具體化視圖。但是,當您手動建立視圖時,您也可以使用底層資料庫中的對應命令建立具體化視圖。然後,您可以使用 Prisma Client 的 TypedSQL 功能來執行命令並手動重新整理視圖。
未來,Prisma Client 可能會支援將個別視圖標記為具體化,並新增 Prisma Client 方法來重新整理具體化視圖。請在我們的 views
回饋 issue 中評論您的使用案例。