Prisma Client API 參考
Prisma Client API 參考文件基於以下 schema
model User {
id Int @id @default(autoincrement())
name String?
email String @unique
profileViews Int @default(0)
role Role @default(USER)
coinflips Boolean[]
posts Post[]
city String
country String
profile ExtendedProfile?
pets Json
}
model ExtendedProfile {
id Int @id @default(autoincrement())
userId Int? @unique
bio String?
User User? @relation(fields: [userId], references: [id])
}
model Post {
id Int @id @default(autoincrement())
title String
published Boolean @default(true)
author User @relation(fields: [authorId], references: [id])
authorId Int
comments Json
views Int @default(0)
likes Int @default(0)
}
enum Role {
USER
ADMIN
}
所有示例生成的型別(例如 UserSelect 和 UserWhereUniqueInput)都基於 User 模型。
PrismaClient
本節描述了 PrismaClient 建構函式及其引數。
備註
- 引數在執行時進行驗證。
datasources
以程式設計方式覆蓋 schema.prisma 檔案中 datasource 塊的屬性 - 例如,作為整合測試的一部分。另請參閱:資料來源
從 5.2.0 版及更高版本開始,您還可以使用 datasourceUrl 屬性以程式設計方式覆蓋資料庫連線字串。
屬性
| 示例屬性 | 示例值 | 描述 |
|---|---|---|
db | { url: 'file:./dev_qa.db' } | 資料庫連線 URL。 |
備註
- 每次新增或重新命名資料來源時,都必須重新生成 Prisma Client。資料來源名稱包含在生成的客戶端中。
- 如果您在 schema 中將
datasource塊命名為其他名稱,請將db替換為您datasource塊的名稱。
示例
以程式設計方式覆蓋資料來源 url
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient({
datasources: {
db: {
url: 'file:./dev_qa.db',
},
},
});
基於以下 datasource 塊
datasource db {
provider = "sqlite"
url = env("DATABASE_URL")
}
datasourceUrl
以程式設計方式覆蓋 schema.prisma 檔案中的 datasource 塊。
屬性
| 選項 | 示例值 | 描述 |
|---|---|---|
| 資料庫連線字串 | 'file:./dev_qa.db' | 資料庫連線 URL。 |
示例
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient({
datasourceUrl: 'postgresql://johndoe:randompassword@localhost:5432/mydb',
});
log
確定日誌的型別和級別。另請參閱:日誌記錄
選項
| 選項 | 示例 |
|---|---|
| 日誌級別陣列 | [ "info", "query" ] |
| 日誌定義陣列 | [ { level: "info", emit: "event" }, { level: "warn", emit: "stdout" }] |
日誌級別
| 名稱 | 示例 |
|---|---|
查詢 | 記錄 Prisma 執行的所有查詢。 對於關係型資料庫,這會記錄所有 SQL 查詢。示例 prisma:query SELECT "public"."User"."id", "public"."User"."email" FROM "public"."User" WHERE ("public"."User"."id") IN (SELECT "t0"."id" FROM "public"."User" AS "t0" INNER JOIN "public"."Post" AS "j0" ON ("j0"."authorId") = ("t0"."id") WHERE ("j0"."views" > $1 AND "t0"."id" IS NOT NULL)) OFFSET $2 對於 MongoDB,這會使用 mongosh shell 格式記錄查詢。示例prisma:query db.User.deleteMany({ _id: ( $in: [ “6221ce49f756b0721fc00542”, ], }, }) |
資訊 | 示例prisma:info Started http server on http://127.0.0.1:58471 |
警告 | 警告。 |
錯誤 | 錯誤。 |
發出格式
| 名稱 | 描述 |
|---|---|
stdout | 參見:標準輸出 |
事件 | 引發您可以訂閱的事件。 |
事件型別
query 事件型別
export type QueryEvent = {
timestamp: Date;
query: string; // Query sent to the database
params: string; // Query parameters
duration: number; // Time elapsed (in milliseconds) between client issuing query and database responding - not only time taken to run query
target: string;
};
請注意,對於 MongoDB,params 和 duration 欄位將未定義。
所有其他日誌級別事件型別
export type LogEvent = {
timestamp: Date;
message: string;
target: string;
};
示例
將 query 和 info 記錄到 stdout
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient({ log: ['query', 'info'] });
async function main() {
const countUsers = await prisma.user.count({});
}
main()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});
將 query 事件記錄到控制檯
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient({
log: [{ level: 'query', emit: 'event' }],
});
prisma.$on('query', (e) => {
console.log(e);
});
async function main() {
const countUsers = await prisma.user.count({});
}
main()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});
將 info、warn 和 error 事件記錄到控制檯
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient({
log: [
{ level: 'warn', emit: 'event' },
{ level: 'info', emit: 'event' },
{ level: 'error', emit: 'event' },
],
});
prisma.$on('warn', (e) => {
console.log(e);
});
prisma.$on('info', (e) => {
console.log(e);
});
prisma.$on('error', (e) => {
console.log(e);
});
async function main() {
const countUsers = await prisma.user.count({});
}
main()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});
errorFormat
確定 Prisma Client 返回的錯誤的級別和格式。
錯誤格式
| 名稱 | 描述 |
|---|---|
未定義 | 如果未定義,預設值為無顏色。 |
漂亮 | 啟用漂亮的錯誤格式。 |
colorless (預設) | 啟用無顏色錯誤格式。 |
最小 | 啟用最小錯誤格式。 |
示例
無錯誤格式
const prisma = new PrismaClient({
// Defaults to colorless
});
pretty 錯誤格式
const prisma = new PrismaClient({
errorFormat: 'pretty',
});
colorless 錯誤格式
const prisma = new PrismaClient({
errorFormat: 'colorless',
});
minimal 錯誤格式
const prisma = new PrismaClient({
errorFormat: 'minimal',
});
adapter
此功能在版本 5.4.0 及更高版本中,並且需要啟用 driverAdapters 功能標誌。
示例
以下示例使用了 Neon 驅動介面卡
import { PrismaNeon } from '@prisma/adapter-neon';
import { PrismaClient } from '@prisma/client';
import dotenv from 'dotenv';
dotenv.config();
const connectionString = `${process.env.DATABASE_URL}`;
const adapter = new PrismaNeon({ connectionString });
const prisma = new PrismaClient({ adapter });
rejectOnNotFound
注意:rejectOnNotFound 在 v5.0.0 中已移除。
已棄用: rejectOnNotFound 在 v4.0.0 中已棄用。從 v4.0.0 開始,請使用查詢 findUniqueOrThrow 或 findFirstOrThrow。
使用 rejectOnNotFound 引數配置 findUnique() 和/或 findFirst,以便在未找到記錄時丟擲錯誤。預設情況下,如果未找到記錄,這兩個操作都會返回 null。
備註
- 您可以為
findUnique()和findFirst配置每個請求級別的rejectOnNotFound
選項
| 選項 | 描述 |
|---|---|
未找到時拒絕 | 全域性啟用(true / false)或丟擲自定義錯誤。 |
每個操作拒絕 | 為每個操作啟用(true / false)或為每個模型、每個操作丟擲自定義錯誤。 |
示例
為 findUnique() 和 findFirst 全域性啟用
const prisma = new PrismaClient({
rejectOnNotFound: true,
});
為特定操作全域性啟用
const prisma = new PrismaClient({
rejectOnNotFound: {
findUnique: true,
},
});
如果未找到記錄,則為每個模型和操作丟擲自定義錯誤
const prisma = new PrismaClient({
rejectOnNotFound: {
findFirst: {
User: (err) => new Error('User error'),
Post: (err) => new Error('Post error!'),
},
findUnique: {
User: (err) => new Error('User error'),
Post: (err) => new Error('Post error!'),
},
},
});
transactionOptions
注意:transactionOptions 在 v5.10.0 中引入。
允許在建構函式級別全域性設定事務選項。
備註
- 事務級別可以在每個事務級別被覆蓋。
選項
| 選項 | 描述 |
|---|---|
最大等待時間 | Prisma Client 從資料庫獲取事務的最大等待時間。預設值為 2 秒。 |
超時 | 互動式事務在被取消和回滾之前可以執行的最大時間。預設值為 5 秒。 |
隔離級別 | 設定事務隔離級別。預設情況下,這設定為您資料庫中當前配置的值。可用值可能因您使用的資料庫而異。 |
示例
const prisma = new PrismaClient({
transactionOptions: {
isolationLevel: Prisma.TransactionIsolationLevel.Serializable,
maxWait: 5000, // default: 2000
timeout: 10000, // default: 5000
},
});
模型查詢
使用模型查詢對您的模型執行 CRUD 操作。另請參閱:CRUD
注意:最佳實踐是在將任何不受信任的使用者資料傳遞到 Prisma 查詢之前,始終對其進行驗證和清理。否則,如果型別檢查被繞過,可能會導致 SQL 注入或其他注入漏洞。確保使用者提供的值不能無意中繞過關鍵檢查。我們強烈建議在應用程式層執行型別檢查和輸入驗證。有關更多詳細資訊,請參閱自定義驗證部分。
findUnique()
findUnique() 查詢允許您檢索單個數據庫記錄
- 按ID
- 按唯一屬性
findUnique() 在 2.12.0 版本中取代了 findOne。
備註
- Prisma Client 的資料載入器自動批處理具有相同
select和where引數的findUnique()查詢。 - 如果您希望查詢在未找到記錄時丟擲錯誤,請考慮改用
findUniqueOrThrow。 - 您不能使用篩選條件(例如
equals、contains、not)來篩選 JSON 資料型別的欄位。使用篩選條件可能會導致該欄位返回null。
選項
| 名稱 | 示例型別(User) | 必需 | 描述 |
|---|---|---|---|
where | UserWhereUniqueInput | 是 | 包裝模型的所有欄位,以便可以選擇記錄(瞭解更多)。 在 4.5.0 版本之前,此型別僅包裝模型的唯一欄位。 |
select | XOR<UserSelect, null> | 否 | 指定返回物件中要包含的屬性。 |
include | XOR<UserInclude, null> | 否 | 指定返回物件中應預載入的關係。 |
omit | XOR<UserOmit, null> | 否 | 指定要從返回物件中排除的屬性。自 5.13.0 版本起進入預覽階段 |
關聯載入策略 | 'join' 或 'query' | 否 | 預設值:join。指定關聯查詢的載入策略。僅與 include(或關聯欄位上的 select)結合使用。自 5.9.0 版本起進入預覽階段。 |
返回型別
| 返回型別 | 示例 | 描述 |
|---|---|---|
| JavaScript 物件(有型別) | User | |
| JavaScript 物件(純文字) | { title: "Hello world" } | 使用 select 和 include 確定要返回的欄位。 |
空 | 空 | 未找到記錄 |
示例
獲取 id 為 42 的 User 記錄
const result = await prisma.user.findUnique({
where: {
id: 42,
},
});
獲取 email 為 alice@prisma.io 的 User 記錄
const result = await prisma.user.findUnique({
where: {
email: 'alice@prisma.io',
},
});
獲取 firstName 為 Alice 和 lastName 為 Smith 的 User 記錄(@@unique)
展開以檢視包含 @@unique 塊的示例 User 模型
model User {
firstName String
lastName String
@@unique(fields: [firstName, lastName], name: "fullname")
}
const result = await prisma.user.findUnique({
where: {
fullname: {
// name property of @@unique attribute - default is firstname_lastname
firstName: 'Alice',
lastName: 'Smith',
},
},
});
獲取 firstName 為 Alice 和 lastName 為 Smith 的 User 記錄(@@id)
展開以檢視包含 @@id 塊的示例 User 模型
model User {
firstName String
lastName String
@@id([firstName, lastName])
}
const result = await prisma.user.findUnique({
where: {
firstName_lastName: {
firstName: 'Alice',
lastName: 'Smith',
},
},
});
findUniqueOrThrow()
findUniqueOrThrow() 以與 findUnique() 相同的方式檢索單個記錄。但是,如果查詢未找到請求的記錄,它會丟擲 PrismaClientKnownRequestError。
請注意,在 Prisma v6 之前,它會丟擲 NotFoundError: No User found error。
以下是其用法示例
await prisma.user.findUniqueOrThrow({
where: { id: 1 },
});
findUniqueOrThrow() 與 findUnique() 的區別如下
-
其返回型別是非空。例如,
post.findUnique()可以返回post或null,但post.findUniqueOrThrow()始終返回post。 -
它與
$transactionAPI 中的順序操作不相容。如果查詢丟擲PrismaClientKnownRequestError,則 API 不會回滾呼叫陣列中的任何操作。作為變通方法,您可以按如下方式使用帶有$transactionAPI 的互動式事務$transaction(async (prisma) => {
await prisma.model.create({ data: { ... });
await prisma.model.findUniqueOrThrow();
})
findFirst()
findFirst 返回列表中符合您條件的第一個記錄。
備註
- 如果您希望查詢在未找到記錄時丟擲錯誤,請考慮改用
findFirstOrThrow。
選項
| 名稱 | 示例型別(User) | 必需 | 描述 |
|---|---|---|---|
select | XOR<UserSelect, null> | 否 | 指定返回物件中要包含的屬性。 |
include | XOR<UserInclude, null> | 否 | 指定返回物件中應預載入的關係。 |
omit | XOR<UserOmit, null> | 否 | 指定要從返回物件中排除的屬性。自 5.13.0 版本起進入預覽階段。 |
關聯載入策略 | 'join' 或 'query' | 否 | 預設值:join。指定關聯查詢的載入策略。僅與 include(或關聯欄位上的 select)結合使用。自 5.9.0 版本起進入預覽階段。 |
where | UserWhereInput | 否 | 將所有模型欄位包裝在型別中,以便可以透過任何屬性篩選列表。 |
orderBy | XOR<Enumerable<UserOrderByInput>, UserOrderByInput> | 否 | 允許您按任何屬性對返回列表進行排序。 |
返回型別
| 返回型別 | 示例 | 描述 |
|---|---|---|
| JavaScript 物件(有型別) | User | 指定要包含在返回物件中的屬性。 |
| JavaScript 物件(純文字) | { title: "Hello world" } | 使用 select 和 include 確定要返回的欄位。 |
空 | 空 | 未找到記錄 |
備註
findFirst在後臺呼叫findMany並接受相同的查詢選項。- 在
findFirst查詢中使用負的take值會反轉列表的順序。
示例
請參閱篩選條件和運算子,瞭解如何篩選結果的示例。
獲取 name 為 Alice 的第一個 User 記錄
const user = await prisma.user.findFirst({
where: { name: 'Alice' },
});
獲取 title 以 A test 開頭的第一個 Post 記錄,使用 take 反轉列表
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient({});
async function main() {
const a = await prisma.post.create({
data: {
title: 'A test 1',
},
});
const b = await prisma.post.create({
data: {
title: 'A test 2',
},
});
const c = await prisma.post.findFirst({
where: {
title: {
startsWith: 'A test',
},
},
orderBy: {
title: 'asc',
},
take: -1, // Reverse the list
});
}
main();
findFirstOrThrow()
findFirstOrThrow() 以與 findFirst() 相同的方式檢索單個數據記錄。但是,如果查詢未找到記錄,它會丟擲 PrismaClientKnownRequestError。
請注意,在 Prisma v6 之前,它會丟擲 NotFoundError: No User found error。
findFirstOrThrow() 與 findFirst() 的區別如下
-
其返回型別是非空。例如,
post.findFirst()可以返回post或null,但post.findFirstOrThrow始終返回post。 -
它與
$transactionAPI 中的順序操作不相容。如果查詢返回PrismaClientKnownRequestError,則 API 不會回滾呼叫陣列中的任何操作。作為變通方法,您可以按如下方式使用帶有$transactionAPI 的互動式事務prisma.$transaction(async (tx) => {
await tx.model.create({ data: { ... });
await tx.model.findFirstOrThrow();
})
findMany()
findMany 返回記錄列表。
選項
| 名稱 | 型別 | 必需 | 描述 |
|---|---|---|---|
select | XOR<PostSelect, null> | 否 | 指定返回物件中要包含的屬性。 |
include | XOR<PostInclude, null> | 否 | 指定返回物件中應預載入的關係。 |
omit | XOR<PostOmit, null> | 否 | 指定要從返回物件中排除的屬性。自 5.13.0 版本起進入預覽階段 |
關聯載入策略 | 'join' 或 'query' | 否 | 預設值:join。指定關聯查詢的載入策略。僅與 include(或關聯欄位上的 select)結合使用。自 5.9.0 版本起進入預覽階段。 |
where | UserWhereInput | 否 | 將所有模型欄位包裝在型別中,以便可以透過任何屬性篩選列表。 |
orderBy | XOR<Enumerable<PostOrderByInput>, PostOrderByInput> | 否 | 允許您按任何屬性對返回列表進行排序。 |
遊標 | UserWhereUniqueInput | 否 | 指定列表的位置(值通常指定 id 或其他唯一值)。 |
take | 數字 | 否 | 指定列表中應返回的物件數量(從列表的開始(正值)或結束(負值)或從指定的 cursor 位置開始計算) |
跳過 | 數字 | 否 | 指定列表中應跳過的返回物件數量。 |
distinct | Enumerable<UserDistinctFieldEnum> | 否 | 允許您按特定欄位過濾掉重複行 - 例如,僅返回不重複的 Post 標題。 |
返回型別
| 返回型別 | 示例 | 描述 |
|---|---|---|
| JavaScript 陣列物件(有型別) | User[] | |
| JavaScript 陣列物件(純文字) | [{ title: "Hello world" }] | 使用 select 和 include 確定要返回的欄位。 |
| 空陣列 | [] | 未找到匹配記錄。 |
示例
請參閱篩選條件和運算子,瞭解如何篩選結果的示例。
獲取所有 name 為 Alice 的 User 記錄
const user = await prisma.user.findMany({
where: { name: 'Alice' },
});
create()
create 建立新的資料庫記錄。
選項
| 名稱 | 型別 | 必需 | 描述 |
|---|---|---|---|
data | XOR<UserCreateInput, UserUncheckedCreateInput> | 是 | 將所有模型欄位包裝在型別中,以便在建立新記錄時提供它們。它還包括關係欄位,允許您執行(事務性)巢狀插入。在資料模型中標記為可選或具有預設值的欄位是可選的。 |
select | XOR<UserSelect, null> | 否 | 指定返回物件中要包含的屬性。 |
include | XOR<UserInclude, null> | 否 | 指定返回物件中應預載入的關係。 |
omit | XOR<UserOmit, null> | 否 | 指定要從返回物件中排除的屬性。自 5.13.0 版本起進入預覽階段 |
關聯載入策略 | 'join' 或 'query' | 否 | 預設值:join。指定關聯查詢的載入策略。僅與 include(或關聯欄位上的 select)結合使用。自 5.9.0 版本起進入預覽階段。 |
返回型別
| 返回型別 | 示例 | 描述 |
|---|---|---|
| JavaScript 物件(有型別) | User | |
| JavaScript 物件(純文字) | { name: "Alice Wonderland" } | 使用 select 和 include 確定要返回的欄位。 |
備註
- 您還可以執行巢狀的
create操作 - 例如,同時新增一個User和兩個Post記錄。
示例
使用唯一必填欄位 email 建立單個新記錄
const user = await prisma.user.create({
data: { email: 'alice@prisma.io' },
});
建立多個新記錄
在大多數情況下,您可以使用 createMany() 或 createManyAndReturn() 查詢執行批次插入。但是,在某些情況下,create() 是插入多條記錄的最佳選擇。
以下示例會生成兩條 INSERT 語句
import { Prisma, PrismaClient } from '@prisma/client';
const prisma = new PrismaClient({ log: ['query'] });
async function main() {
let users: Prisma.UserCreateInput[] = [
{
email: 'ariana@prisma.io',
name: 'Ari',
profileViews: 20,
coinflips: [true, false, false],
role: 'ADMIN',
},
{
email: 'elsa@prisma.io',
name: 'Elsa',
profileViews: 20,
coinflips: [true, false, false],
role: 'ADMIN',
},
];
await Promise.all(
users.map(async (user) => {
await prisma.user.create({
data: user,
});
})
);
}
main()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});
prisma:query BEGIN
prisma:query INSERT INTO "public"."User" ("name","email","profileViews","role","coinflips") VALUES ($1,$2,$3,$4,$5) RETURNING "public"."User"."id"
prisma:query SELECT "public"."User"."id", "public"."User"."name", "public"."User"."email", "public"."User"."profileViews", "public"."User"."role", "public"."User"."coinflips" FROM "public"."User" WHERE "public"."User"."id" = $1 LIMIT $2 OFFSET $3
prisma:query INSERT INTO "public"."User" ("name","email","profileViews","role","coinflips") VALUES ($1,$2,$3,$4,$5) RETURNING "public"."User"."id"
prisma:query COMMIT
prisma:query SELECT "public"."User"."id", "public"."User"."name", "public"."User"."email", "public"."User"."profileViews", "public"."User"."role", "public"."User"."coinflips" FROM "public"."User" WHERE "public"."User"."id" = $1 LIMIT $2 OFFSET $3
prisma:query COMMIT
update()
update 更新現有資料庫記錄。
選項
| 名稱 | 型別 | 必需 | 描述 |
|---|---|---|---|
data | XOR<UserUpdateInputUserUncheckedUpdateInput> | 是 | 將模型的所有欄位包裝在型別中,以便在更新現有記錄時提供它們。在資料模型中標記為可選或具有預設值的欄位是可選的。 |
where | UserWhereUniqueInput | 是 | 包裝模型的所有欄位,以便可以選擇記錄(瞭解更多)。 在 4.5.0 版本之前,此型別僅包裝模型的唯一欄位。 |
select | XOR<UserSelect, null> | 否 | 指定返回物件中要包含的屬性。 |
include | XOR<UserInclude, null> | 否 | 指定返回物件中應預載入的關係。 |
omit | XOR<UserOmit, null> | 否 | 指定要從返回物件中排除的屬性。自 5.13.0 版本起進入預覽階段。 |
關聯載入策略 | 'join' 或 'query' | 否 | 預設值:join。指定關聯查詢的載入策略。僅與 include(或關聯欄位上的 select)結合使用。自 5.9.0 版本起進入預覽階段。 |
返回型別
| 返回型別 | 示例 | 描述 |
|---|---|---|
| JavaScript 物件(有型別) | User | |
| JavaScript 物件(純文字) | { name: "Alice Wonderland" } | 使用 select 和 include 確定要返回的欄位。 |
RecordNotFound 異常 | 如果記錄不存在,則丟擲異常。 |
備註
示例
將 id 為 1 的 User 記錄的 email 更新為 alice@prisma.io
const user = await prisma.user.update({
where: { id: 1 },
data: { email: 'alice@prisma.io' },
});
upsert()
本節涵蓋 upsert() 操作的用法。要了解如何在 update() 中使用 巢狀 upsert 查詢,請參閱連結文件。
upsert 執行以下操作
- 如果現有資料庫記錄滿足
where條件,則更新該記錄 - 如果沒有資料庫記錄滿足
where條件,則建立新的資料庫記錄
選項
| 名稱 | 型別 | 必需 | 描述 |
|---|---|---|---|
建立 | XOR<UserCreateInput,UserUncheckedCreateInput> | 是 | 將模型的所有欄位包裝在型別中,以便在建立新記錄時提供它們。它還包括關係欄位,允許您執行(事務性)巢狀插入。在資料模型中標記為可選或具有預設值的欄位是可選的。 |
更新 | XOR<UserUpdateInput,UserUncheckedUpdateInput> | 是 | 將模型的所有欄位包裝在型別中,以便在更新現有記錄時提供它們。在資料模型中標記為可選或具有預設值的欄位是可選的。 |
where | UserWhereUniqueInput | 是 | 包裝模型的所有欄位,以便可以選擇記錄(瞭解更多)。 在 4.5.0 版本之前,此型別僅包裝模型的唯一欄位。 |
select | XOR<UserSelect, null> | 否 | 指定返回物件中要包含的屬性。 |
include | XOR<UserInclude, null> | 否 | 指定返回物件中應預載入的關係。 |
omit | XOR<UserOmit, null> | 否 | 指定要從返回物件中排除的屬性。自 5.13.0 版本起進入預覽階段 |
關聯載入策略 | 'join' 或 'query' | 否 | 預設值:join。指定關聯查詢的載入策略。僅與 include(或關聯欄位上的 select)結合使用。自 5.9.0 版本起進入預覽階段。 |
返回型別
| 返回型別 | 示例 | 描述 |
|---|---|---|
| JavaScript 物件(有型別) | User | |
| JavaScript 物件(純文字) | { name: "Alice Wonderland" } | 使用 select 和 include 確定要返回的欄位。 |
備註
- 要在更新時執行算術運算(加、減、乘、除),請使用原子更新以防止競態條件。
- 如果同時發生兩個或多個 upsert 操作且記錄尚不存在,則可能會發生競態條件。結果,一個或多個 upsert 操作可能會丟擲唯一鍵約束錯誤。您的應用程式程式碼可以捕獲此錯誤並重試該操作。瞭解更多。
- 從 4.6.0 版本開始,Prisma ORM 會盡可能將 upsert 查詢交給資料庫處理。瞭解更多。
示例
更新(如果存在)或建立電子郵件為 alice@prisma.io 的新 User 記錄
const user = await prisma.user.upsert({
where: { id: 1 },
update: { email: 'alice@prisma.io' },
create: { email: 'alice@prisma.io' },
});
upsert 上的唯一鍵約束錯誤
問題
如果同時發生多個 upsert 操作且記錄尚不存在,則一個或多個操作可能會返回唯一鍵約束錯誤。
原因
當 Prisma Client 執行 upsert 操作時,它首先檢查該記錄是否已存在於資料庫中。為了執行此檢查,Prisma Client 使用 upsert 操作中的 where 子句執行讀取操作。這有兩種可能的結果,如下所示
- 如果記錄不存在,則 Prisma Client 建立該記錄。
- 如果記錄存在,則 Prisma Client 更新它。
當您的應用程式嘗試執行兩個或更多併發 upsert 操作時,可能會發生競態條件,即兩個或更多操作未找到記錄,因此嘗試建立該記錄。在這種情況下,其中一個操作成功建立新記錄,但其他操作失敗並返回唯一鍵約束錯誤。
解決方案
在您的應用程式程式碼中處理 P2002 錯誤。當它發生時,重試 upsert 操作以更新該行。
資料庫 upsert
如果可能,Prisma Client 會將 upsert 查詢交給資料庫處理。這稱為資料庫 upsert。
資料庫 upsert 具有以下優點
- 它們比 Prisma Client 處理的 upsert 更快
- 唯一鍵約束錯誤不會發生
當滿足特定條件時,Prisma Client 會自動使用資料庫 upsert。當不滿足這些條件時,Prisma Client 會處理 upsert。
要使用資料庫 upsert,Prisma Client 會向資料庫傳送 SQL 構造 INSERT ... ON CONFLICT SET .. WHERE。
資料庫 upsert 前提條件
如果您的技術棧滿足以下條件,Prisma Client 可以使用資料庫 upsert
- 您使用 Prisma ORM 4.6.0 或更高版本
- 您的應用程式使用 CockroachDB、PostgreSQL 或 SQLite 資料來源
資料庫 upsert 查詢條件
當 upsert 查詢滿足以下條件時,Prisma Client 會使用資料庫 upsert
upsert的create和update選項中沒有巢狀查詢- 查詢不包含使用巢狀讀取的選擇
- 查詢僅修改一個模型
upsert的where選項中只有一個唯一欄位where選項中的唯一欄位與create選項中的唯一欄位具有相同的值
如果您的查詢不滿足這些條件,則 Prisma Client 會自行處理 upsert。
資料庫 upsert 示例
以下示例使用此 schema
model User {
id Int @id
profileViews Int
userName String @unique
email String
@@unique([id, profileViews])
}
以下 upsert 查詢滿足所有條件,因此 Prisma Client 使用資料庫 upsert。
prisma.user.upsert({
where: {
userName: 'Alice',
},
create: {
id: 1,
profileViews: 1,
userName: 'Alice',
email: 'alice@prisma.io',
},
update: {
email: 'updated@example.com',
},
});
在這種情況下,Prisma 使用以下 SQL 查詢
INSERT INTO "public"."User" ("id","profileViews","userName","email") VALUES ($1,$2,$3,$4)
ON CONFLICT ("userName") DO UPDATE
SET "email" = $5 WHERE ("public"."User"."userName" = $6 AND 1=1) RETURNING "public"."User"."id", "public"."User"."profileViews", "public"."User"."userName", "public"."User"."email"
以下查詢的 where 子句中有多個唯一值,因此 Prisma Client 不使用資料庫 upsert
prisma.User.upsert({
where: {
userName: 'Alice',
profileViews: 1,
id: 1,
},
create: {
id: 1,
profileViews: 1,
userName: 'Alice',
email: 'alice@prisma.io',
},
update: {
email: 'updated@example.com',
},
});
在以下查詢中,where 和 create 選項中 userName 的值不同,因此 Prisma Client 不使用資料庫 upsert。
prisma.User.upsert({
where: {
userName: 'Alice',
},
create: {
id: 1,
profileViews: 1,
userName: 'AliceS',
email: 'alice@prisma.io',
},
update: {
email: 'updated@example.com',
},
});
在以下查詢中,posts 中 title 欄位的選擇是巢狀讀取,因此 Prisma Client 不使用資料庫 upsert。
prisma.user.upsert({
select: {
email: true,
id: true,
posts: {
select: {
title: true,
},
},
},
where: {
userName: 'Alice',
},
create: {
id: 1,
profileViews: 1,
userName: 'Alice',
email: 'alice@prisma.io',
},
update: {
email: 'updated@example.com',
},
});
delete()
delete 刪除現有資料庫記錄。您可以刪除記錄
- 按ID
- 按唯一屬性
要刪除符合特定條件的記錄,請使用帶有過濾器的 deleteMany。
選項
| 名稱 | 型別 | 必需 | 描述 |
|---|---|---|---|
where | UserWhereUniqueInput | 是 | 包裝模型的所有欄位,以便可以選擇記錄(瞭解更多)。 在 4.5.0 版本之前,此型別僅包裝模型的唯一欄位。 |
select | XOR<UserSelect, null> | 否 | 指定返回物件中要包含的屬性。 |
include | XOR<UserInclude, null> | 否 | 指定返回物件中應預載入的關係。 |
omit | XOR<UserOmit, null> | 否 | 指定要從返回物件中排除的屬性。自 5.13.0 版本起進入預覽階段 |
關聯載入策略 | 'join' 或 'query' | 否 | 預設值:join。指定關聯查詢的載入策略。僅與 include(或關聯欄位上的 select)結合使用。自 5.9.0 版本起進入預覽階段。 |
返回型別
| 返回型別 | 示例 | 描述 |
|---|---|---|
| JavaScript 物件(有型別) | User | 已刪除的 User 記錄。 |
| JavaScript 物件(純文字) | { name: "Alice Wonderland" } | 已刪除的 User 記錄中的資料。使用 select 和 include 確定要返回的欄位。 |
RecordNotFound 異常 | 如果記錄不存在,則丟擲異常。 |
備註
- 要根據某些條件刪除多條記錄(例如,所有電子郵件地址為
prisma.io的User記錄,請使用deleteMany)
示例
刪除 id 為 1 的 User 記錄
const user = await prisma.user.delete({
where: { id: 1 },
});
刪除 email 等於 else@prisma.io 的 User 記錄
以下查詢刪除特定使用者記錄,並使用 select 返回已刪除使用者的 name 和 email
const deleteUser = await prisma.user.delete({
where: {
email: 'elsa@prisma.io',
},
select: {
email: true,
name: true,
},
});
{ "email": "elsa@prisma.io", "name": "Elsa" }
createMany()
createMany 在一個事務中建立多條記錄。
選項
| 名稱 | 型別 | 必需 | 描述 |
|---|---|---|---|
data | Enumerable<UserCreateManyInput> | 是 | 將所有模型欄位包裝在型別中,以便在建立新記錄時提供它們。在資料模型中標記為可選或具有預設值的欄位是可選的。 |
skipDuplicates? | 布林 | 否 | 不插入具有已存在唯一欄位或 ID 欄位的記錄。僅受支援 ON CONFLICT DO NOTHING 的資料庫支援。這不包括 MongoDB 和 SQLServer |
返回型別
| 返回型別 | 示例 | 描述 |
|---|---|---|
BatchPayload | { count: 3 } | 建立的記錄數量。 |
備註
- 自 Prisma ORM 5.12.0 版本起,SQLite 現已支援
createMany()。 - MongoDB、SQLServer 或 SQLite 不支援
skipDuplicates選項。 - 您不能透過在頂級
createMany()查詢中使用巢狀的create、createMany、connect、connectOrCreate查詢來建立或連線關係。請參閱此處以獲取解決方法。 - 您可以在
update()或create()查詢中巢狀使用createMany查詢 - 例如,同時新增一個User和兩個Post記錄,並進行巢狀的createMany。
示例
建立多個新使用者
const users = await prisma.user.createMany({
data: [
{ name: 'Sonali', email: 'sonali@prisma.io' },
{ name: 'Alex', email: 'alex@prisma.io' },
],
});
createManyAndReturn()
createManyAndReturn 建立多條記錄並返回結果物件。
此功能在 Prisma ORM 5.14.0 及更高版本中可用,適用於 PostgreSQL、CockroachDB 和 SQLite。
選項
| 名稱 | 型別 | 必需 | 描述 |
|---|---|---|---|
data | Enumerable<UserCreateManyInput> | 是 | 將所有模型欄位包裝在型別中,以便在建立新記錄時提供它們。在資料模型中標記為可選或具有預設值的欄位是可選的。 |
select | XOR<UserSelect, null> | 否 | 指定要在返回物件中包含的屬性。 |
omit | XOR<UserOmit, null> | 否 | 指定要從返回物件中排除的屬性。自 5.13.0 版本起進入預覽階段。與 select 互斥。 |
include | XOR<UserInclude, null> | 否 | 指定在返回物件中應預載入哪些關係。 |
skipDuplicates? | 布林 | 否 | 不插入具有已存在唯一欄位或 ID 欄位的記錄。僅受支援 ON CONFLICT DO NOTHING 的資料庫支援。這不包括 MongoDB 和 SQLServer |
備註
- SQLite 不支援
skipDuplicates選項。 - 請注意,
createManyAndReturn返回的元素順序不保證。 - 您不能透過在頂級
createManyAndReturn()查詢中巢狀使用create、createMany、connect、connectOrCreate查詢來建立或連線關係。請參閱此處以獲取解決方法。 - 當關系透過
include包含時,會為每個關係生成一個單獨的查詢。 - 不支援
relationLoadStrategy: join。
返回型別
| 返回型別 | 示例 | 描述 |
|---|---|---|
| JavaScript 陣列物件(有型別) | User[] | |
| JavaScript 陣列物件(純文字) | [{ name: "Sonali" }] | 使用 select、omit 和 include 確定要返回的欄位。 |
示例
建立並返回多個新使用者
const users = await prisma.user.createManyAndReturn({
data: [
{ name: 'Sonali', email: 'sonali@prisma.io' },
{ name: 'Alex', email: 'alex@prisma.io' },
],
})
[
{ "id": 0, "name": "Sonali", "email": "sonali@prisma.io", "profileViews": 0 },
{ "id": 1, "name": "Alex", "email": "alex@prisma.io", "profileViews": 0 }
]
updateMany()
updateMany 批次更新現有資料庫記錄並返回更新的記錄數量。
選項
| 名稱 | 型別 | 必需 | 描述 |
|---|---|---|---|
data | XOR<UserUpdateManyMutationInput,UserUncheckedUpdateManyInput> | 是 | 將模型的所有欄位包裝在型別中,以便在更新現有記錄時提供它們。在資料模型中標記為可選或具有預設值的欄位在 data 上是可選的。 |
where | UserWhereInput | 否 | 將模型的所有欄位包裝在型別中,以便可以透過任何屬性過濾列表。如果您不過濾列表,則所有記錄都將被更新。 |
限制 | 數字 | 否 | 限制更新的記錄數量。 |
返回型別
| 返回型別 | 示例 | 描述 |
|---|---|---|
BatchPayload | { count: 4 } | 已更新記錄的數量。 |
export type BatchPayload = {
count: number;
};
示例
將所有 name 為 Alice 的 User 記錄更新為 ALICE
const updatedUserCount = await prisma.user.updateMany({
where: { name: 'Alice' },
data: { name: 'ALICE' },
});
更新所有 email 包含 prisma.io 且至少一篇相關 Post 點贊數超過 10 的 User 記錄
const updatedUserCount = await prisma.user.updateMany({
where: {
email: {
contains: 'prisma.io',
},
posts: {
some: {
likes: {
gt: 10,
},
},
},
},
data: {
role: 'USER',
},
});
更新 email 包含 prisma.io 的 User 記錄,但限制更新 5 條記錄。
const updatedUserCount = await prisma.user.updateMany({
where: {
email: {
contains: 'prisma.io',
},
},
data: {
role: 'USER',
},
limit: 5,
});
updateManyAndReturn()
此功能在 Prisma ORM 6.2.0 及更高版本中可用,適用於 PostgreSQL、CockroachDB 和 SQLite。
updateManyAndReturn 更新多條記錄並返回結果物件。
選項
| 名稱 | 型別 | 必需 | 描述 |
|---|---|---|---|
data | XOR<UserUpdateManyMutationInput,UserUncheckedUpdateManyInput> | 是 | 將模型的所有欄位包裝在型別中,以便在更新現有記錄時提供它們。在資料模型中標記為可選或具有預設值的欄位在 data 上是可選的。 |
where | UserWhereInput | 否 | 將模型的所有欄位包裝在型別中,以便可以透過任何屬性過濾列表。如果您不過濾列表,則所有記錄都將被更新。 |
返回型別
| 返回型別 | 示例 | 描述 |
|---|---|---|
| JavaScript 陣列物件(有型別) | User[] | |
| JavaScript 陣列物件(純文字) | [{ name: "Sonali" }] | 使用 select、omit 和 include 確定要返回的欄位。 |
示例
更新並返回多個使用者
const users = await prisma.user.updateManyAndReturn({
where: {
email: {
contains: 'prisma.io',
}
},
data: {
role: 'ADMIN'
},
})
[
{ "id": 0, "name": "Sonali", "email": "sonali@prisma.io", "role": "ADMIN", "profileViews": 0 },
{ "id": 1, "name": "Alex", "email": "alex@prisma.io", "role": "ADMIN", "profileViews": 0 }
]
deleteMany()
deleteMany 在一個事務中刪除多條記錄。
選項
| 名稱 | 型別 | 必需 | 描述 |
|---|---|---|---|
where | UserWhereInput | 否 | 將模型的所有欄位包裝在型別中,以便可以透過任何欄位進行篩選。 |
限制 | 整數 | 否 | 限制刪除的記錄數量。 |
返回型別
| 返回型別 | 示例 | 描述 |
|---|---|---|
BatchPayload | { count: 4 } | 已刪除記錄的數量。 |
export type BatchPayload = {
count: number;
};
示例
刪除所有 User 記錄
const deletedUserCount = await prisma.user.deleteMany({});
刪除所有 name 為 Alice 的 User 記錄
const deletedUserCount = await prisma.user.deleteMany({
where: { name: 'Alice' },
});
刪除所有 email 包含 prisma.io 的 User 記錄,但限制刪除 5 條記錄。
const deletedUserCount = await prisma.user.deleteMany({
where: {
email: {
contains: 'prisma.io',
},
},
limit: 5,
});
請參閱篩選條件和運算子,瞭解如何篩選要刪除的記錄的示例。
count()
選項
| 名稱 | 型別 | 必需 | 描述 |
|---|---|---|---|
where | UserWhereInput | 否 | 將所有模型欄位包裝在型別中,以便可以透過任何屬性篩選列表。 |
orderBy | XOR<Enumerable<PostOrderByInput>, PostOrderByInput> | 否 | 允許您按任何屬性對返回列表進行排序。 |
遊標 | UserWhereUniqueInput | 否 | 指定列表的位置(值通常指定 id 或其他唯一值)。 |
take | 數字 | 否 | 指定列表中應返回的物件數量(從列表的開始(正值)或結束(負值)或從指定的 cursor 位置開始計算) |
跳過 | 數字 | 否 | 指定列表中應跳過的返回物件數量。 |
返回型別
| 返回型別 | 示例 | 描述 |
|---|---|---|
數字 | 29 | 記錄的數量。 |
UserCountAggregateOutputType | { _all: 27, name: 10 } | 如果使用了 select 則返回。 |
示例
統計所有 User 記錄
const result = await prisma.user.count();
統計所有至少有一篇已釋出 Post 的 User 記錄
const result = await prisma.user.count({
where: {
post: {
some: {
published: true,
},
},
},
});
使用 select 執行三個獨立的計數
以下查詢返回
- 所有記錄的數量 (
_all) - 所有
name欄位非null的記錄的數量 - 所有
city欄位非null的記錄的數量
const c = await prisma.user.count({
select: {
_all: true,
city: true,
name: true,
},
});
aggregate()
另請參閱:聚合、分組和彙總
選項
| 名稱 | 型別 | 必需 | 描述 |
|---|---|---|---|
where | UserWhereInput | 否 | 將所有模型欄位包裝在型別中,以便可以透過任何屬性篩選列表。 |
orderBy | XOR<Enumerable<UserOrderByInput>,UserOrderByInput> | 否 | 允許您按任何屬性對返回列表進行排序。 |
遊標 | UserWhereUniqueInput | 否 | 指定列表的位置(值通常指定 id 或其他唯一值)。 |
take | 數字 | 否 | 指定列表中應返回的物件數量(從列表的開始(正值)或結束(負值)或從指定的 cursor 位置開始計算) |
跳過 | 數字 | 否 | 指定列表中應跳過的返回物件數量。 |
_count | 真 | 否 | 返回匹配記錄或非 null 欄位的計數。 |
_avg | UserAvgAggregateInputType | 否 | 返回指定欄位所有值的平均值。 |
_sum | UserSumAggregateInputType | 否 | 返回指定欄位所有值的總和。 |
_min | UserMinAggregateInputType | 否 | 返回指定欄位的最小可用值。 |
_max | UserMaxAggregateInputType | 否 | 返回指定欄位的最大可用值。 |
示例
返回所有 User 記錄的 profileViews 的 _min、_max 和 _count
const minMaxAge = await prisma.user.aggregate({
_count: {
_all: true,
},
_max: {
profileViews: true,
},
_min: {
profileViews: true,
},
});
返回所有 User 記錄的 profileViews 的 _sum
const setValue = await prisma.user.aggregate({
_sum: {
profileViews: true,
},
});
groupBy()
另請參閱:聚合、分組和彙總
選項
| 名稱 | 型別 | 必需 | 描述 |
|---|---|---|---|
where | UserWhereInput | 否 | 將所有模型欄位包裝在型別中,以便可以透過任何屬性篩選列表。 |
orderBy | XOR<Enumerable<UserOrderByInput>,UserOrderByInput> | 否 | 允許您根據 by 中也存在的任何屬性對返回列表進行排序。 |
by | Array<UserScalarFieldEnum> | string | 否 | 指定用於分組記錄的欄位或欄位組合。 |
having | UserScalarWhereWithAggregatesInput | 否 | 允許您按聚合值過濾組 - 例如,僅返回平均年齡小於 50 的組。 |
take | 數字 | 否 | 指定列表中應返回的物件數量(從列表的開始(正值)或結束(負值)或從指定的 cursor 位置開始計算) |
跳過 | 數字 | 否 | 指定列表中應跳過的返回物件數量。 |
_count | true | UserCountAggregateInputType | 否 | 返回匹配記錄或非 null 欄位的計數。 |
_avg | UserAvgAggregateInputType | 否 | 返回指定欄位所有值的平均值。 |
_sum | UserSumAggregateInputType | 否 | 返回指定欄位所有值的總和。 |
_min | UserMinAggregateInputType | 否 | 返回指定欄位的最小可用值。 |
_max | UserMaxAggregateInputType | 否 | 返回指定欄位的最大可用值。 |
示例
按 country/city 分組,其中平均 profileViews 大於 200,並返回每個組的 profileViews 的 _sum
該查詢還返回每個組中 _all 記錄的計數,以及每個組中 city 欄位值非 null 的所有記錄。
const groupUsers = await prisma.user.groupBy({
by: ['country', 'city'],
_count: {
_all: true,
city: true,
},
_sum: {
profileViews: true,
},
orderBy: {
country: 'desc',
},
having: {
profileViews: {
_avg: {
gt: 200,
},
},
},
});
[
{
country: 'Denmark',
city: 'Copenhagen',
_sum: { profileViews: 490 },
_count: {
_all: 70,
city: 8,
},
},
{
country: 'Sweden',
city: 'Stockholm',
_sum: { profileViews: 500 },
_count: {
_all: 50,
city: 3,
},
},
];
findRaw()
aggregateRaw()
模型查詢選項
select
select 定義 Prisma Client 返回的物件中包含哪些欄位。參見:選擇欄位幷包含關係。
備註
- 您不能在同一級別同時使用
select和include。 - 在 3.0.1 及更高版本中,您可以選擇關係的
_count。
示例
選擇單個 User 記錄的 name 和 profileViews 欄位
const result = await prisma.user.findUnique({
where: { id: 1 },
select: {
name: true,
profileViews: true,
},
});
選擇多個 User 記錄的 email 和 role 欄位
const result = await prisma.user.findMany({
select: {
email: true,
role: true,
},
});
選擇關係的 _count
const usersWithCount = await prisma.user.findMany({
select: {
_count: {
select: { posts: true },
},
},
});
選擇相關 Post 記錄的 'id' 和 'title' 欄位
const result = await prisma.user.findMany({
select: {
id: true,
name: true,
posts: {
select: {
id: true,
title: true,
},
},
},
});
select 中的 include
const result = await prisma.user.findMany({
select: {
id: true,
name: true,
posts: {
include: {
author: true,
},
},
},
});
select 的生成型別
以下示例演示瞭如何將 validator 與 select 一起使用
const selectNameEmailNotPosts = Prisma.validator<Prisma.UserSelect>()({
name: true,
email: true,
posts: false,
});
include
include 定義了 Prisma Client 返回的結果中包含哪些關係。參見:選擇欄位幷包含關係。
備註
- 在 3.0.1 及更高版本中,您可以
include關係的_count
示例
在載入 User 記錄時包含 posts 和 profile 關係
const users = await prisma.user.findMany({
include: {
posts: true, // Returns all fields for all posts
profile: true, // Returns all Profile fields
},
});
在建立包含兩條 Post 記錄的新 User 記錄時,在返回的物件中包含 posts 關係
const user = await prisma.user.create({
data: {
email: 'alice@prisma.io',
posts: {
create: [{ title: 'This is my first post' }, { title: 'Here comes a second post' }],
},
},
include: { posts: true }, // Returns all fields for all posts
});
include 的生成型別
以下示例演示瞭如何將 validator 與 include 一起使用
const includePosts = Prisma.validator<Prisma.UserInclude>()({
posts: true,
});
包含關係的 _count
const usersWithCount = await prisma.user.findMany({
include: {
_count: {
select: { posts: true },
},
},
});
omit
omit 定義了 Prisma Client 返回的物件中排除哪些欄位。
備註
- 您不能同時使用
omit和select,因為它們的目的相反 omit隨 Prisma ORM 6.2.0 釋出到通用版本。在 Prisma ORM5.13.0到6.1.0版本中,它透過omitApi預覽功能提供。
示例
從所有 User 記錄中省略 password 欄位
const result = await prisma.user.findMany({
omit: {
password: true,
},
});
從所有 User 的 posts 關係中省略 title 欄位
const results = await prisma.user.findMany({
omit: {
password: true,
},
include: {
posts: {
omit: {
title: true,
},
},
},
});
omit 的生成型別
以下示例演示瞭如何將 validator 與 omit 一起使用
const omitPassword = Prisma.validator<Prisma.UserOmit>()({
password: true,
});
relationLoadStrategy(預覽)
relationLoadStrategy 指定如何從資料庫載入關係。它有兩個可能的值
join(預設):使用資料庫級別的LATERAL JOIN(PostgreSQL)或相關子查詢(MySQL),並透過單個查詢從資料庫獲取所有資料。query:向資料庫傳送多個查詢(每個表一個),並在應用程式級別進行連線。
注意:一旦
relationLoadStrategy從預覽階段進入通用可用階段,join將普遍成為所有關係查詢的預設值。
您可以在此處瞭解有關連線策略的更多資訊。
由於 relationLoadStrategy 選專案前處於預覽階段,您需要在 Prisma schema 檔案中透過 relationJoins 預覽功能標誌啟用它
generator client {
provider = "prisma-client-js"
previewFeatures = ["relationJoins"]
}
新增此標誌後,您需要再次執行 prisma generate 以重新生成 Prisma Client。relationJoins 功能目前在 PostgreSQL、CockroachDB 和 MySQL 上可用。
備註
- 在大多數情況下,預設的
join策略會更有效。如果您想節省資料庫伺服器上的資源,或者如果您的效能分析顯示應用程式級連線效能更好,請使用query。 - 您只能在查詢的頂層指定
relationLoadStrategy。頂層選擇將影響所有巢狀的子查詢。
示例
使用 include 時,透過資料庫級別 JOIN 載入 posts 關係
const users = await prisma.user.findMany({
relationLoadStrategy: 'join',
include: {
posts: true,
},
});
使用 select 時,透過資料庫級別 JOIN 載入 posts 關係
const users = await prisma.user.findMany({
relationLoadStrategy: 'join',
select: {
posts: true,
},
});
where
where 定義一個或多個過濾器,可用於篩選記錄屬性(如使用者的電子郵件地址)或相關記錄屬性(如使用者最近 10 篇最熱門帖子標題)。
示例
const results = await prisma.user.findMany({
where: {
email: {
endsWith: 'prisma.io',
},
},
});
where 的生成型別
以下示例演示瞭如何將 validator 與 where 一起使用
-
UserWhereInput// UserWhereInput
const whereNameIs = Prisma.validator<Prisma.UserWhereInput>()({
name: 'Rich',
});
// It can be combined with conditional operators too
const whereNameIs = Prisma.validator<Prisma.UserWhereInput>()({
name: 'Rich',
AND: [
{
email: {
contains: 'rich@boop.com',
},
},
],
}); -
UserWhereUniqueInput此型別透過公開模型上的任何唯一欄位來工作。被指定為@id的欄位被認為是唯一的,被指定為@unique的欄位也是如此。從 4.5.0 版本開始,此型別公開模型上的所有欄位。這意味著當您根據唯一欄位篩選單個記錄時,您可以同時檢查額外的非唯一欄位和唯一欄位。 瞭解更多。
// UserWhereUniqueInput
const whereEmailIsUnique = Prisma.validator<Prisma.UserWhereUniqueInput>()({
email: 'rich@boop.com',
}) -
PostScalarWhereInputconst whereScalarTitleIs = Prisma.validator<Prisma.PostScalarWhereInput>()({
title: 'boop',
}); -
PostUpdateWithWhereUniqueWithoutAuthorInput- 此型別接受一個唯一的where欄位(一個@id或另一個指定的@unique),並更新Post模型上除Author之外的任何欄位。Author是Post模型上的標量欄位。const updatePostByIdWithoutAuthor =
Prisma.validator<Prisma.PostUpdateWithWhereUniqueWithoutAuthorInput>()({
where: {
id: 1,
},
data: {
content: 'This is some updated content',
published: true,
title: 'This is a new title',
},
}); -
PostUpsertWithWhereUniqueWithoutAuthorInput- 此型別將更新Post記錄的標題欄位,其中 id 匹配,如果不存在則會建立它。const updatePostTitleOrCreateIfNotExist =
Prisma.validator<Prisma.PostUpsertWithWhereUniqueWithoutAuthorInput>()({
where: {
id: 1,
},
update: {
title: 'This is a new title',
},
create: {
id: 1,
title: 'If the title doesnt exist, then create one with this text',
},
}); -
PostUpdateManyWithWhereWithoutAuthorInput- 此型別將更新所有Post記錄,其中 published 設定為 false。const publishAllPosts = Prisma.validator<Prisma.PostUpdateManyWithWhereWithoutAuthorInput>()({
where: {
published: {
equals: false,
},
},
data: {
published: true,
},
});
orderBy
對記錄列表進行排序。另請參閱:排序
備註
-
在 4.1.0 及更高版本中,您可以將
null記錄排在最前或最後。欲瞭解詳情,請參閱將 null 值排在最前或最後。
sort 引數的輸入
| 名稱 | 描述 |
|---|---|
asc | 升序排序(A → Z) |
desc | 降序排序(Z → A) |
nulls 引數的輸入
注意
- 此引數是可選的。
- 它僅用於可選的標量欄位。如果您嘗試在必填或關聯欄位上按 null 值排序,Prisma Client 將丟擲 P2009 錯誤。
- 此功能在 4.1.0 及更高版本中可用,作為預覽功能。有關如何啟用此功能的詳細資訊,請參閱將 null 值排在最前或最後。
| 名稱 | 描述 |
|---|---|
first | 將 null 值排在最前。 |
last | 將 null 值排在最後。 |
示例
按 email 欄位排序 User
以下示例返回所有按 email 升序排序的 User 記錄
const users = await prisma.user.findMany({
orderBy: {
email: 'asc',
},
});
以下示例返回所有按 email 降序排序的 User 記錄
const users = await prisma.user.findMany({
orderBy: {
email: 'desc',
},
});
按關聯的 User 記錄的 name 排序 Post
以下查詢按使用者姓名排序帖子
const posts = await prisma.post.findMany({
orderBy: {
author: {
name: 'asc',
},
},
});
按關聯的 User 記錄的 name 排序 Post,null 記錄優先
以下查詢按使用者姓名排序帖子,null 記錄優先
const posts = await prisma.post.findMany({
orderBy: {
author: {
name: { sort: 'asc', nulls: 'first' },
},
},
});
按標題相關性排序 Post
對於 PostgreSQL,此功能仍處於預覽階段。要使用它,請啟用 fullTextSearchPostgres 功能標誌。
以下查詢按搜尋詞 'database' 與標題的相關性對帖子進行排序
const posts = await prisma.post.findMany({
orderBy: {
_relevance: {
fields: ['title'],
search: 'database',
sort: 'asc'
},
})
按 posts 數量排序 User
以下查詢按帖子數量排序使用者
const getActiveusers = await prisma.user.findMany({
orderBy: {
posts: {
count: 'desc',
},
},
});
按多個欄位排序 User - email 和 role
以下示例按兩個欄位排序使用者 - 首先是 email,然後是 role
const users = await prisma.user.findMany({
select: {
email: true,
role: true,
},
orderBy: [
{
email: 'desc',
},
{
role: 'desc',
},
],
});
排序引數的順序很重要 - 以下查詢按 role 排序,然後按 email 排序。注意結果差異
const users = await prisma.user.findMany({
select: {
email: true,
role: true,
},
orderBy: [
{
role: 'desc',
},
{
email: 'desc',
},
],
});
按 email 排序 User,選擇 name 和 email
以下示例返回所有 User 記錄的 name 和 email 欄位,按 email 排序
const users3 = await prisma.user.findMany({
orderBy: {
email: 'asc',
},
select: {
name: true,
email: true,
},
});
按 email 排序 User 記錄並按 title 排序巢狀的 Post 記錄
以下示例
- 返回所有按
email排序的User記錄 - 對於每個
User記錄,返回所有按title排序的巢狀Post記錄的title欄位
const usersWithPosts = await prisma.user.findMany({
orderBy: {
email: 'asc',
},
include: {
posts: {
select: {
title: true,
},
orderBy: {
title: 'asc',
},
},
},
});
排序單個使用者的巢狀 Post 記錄列表
以下示例透過 ID 檢索單個 User 記錄,以及按 title 排序的巢狀 Post 記錄列表
const userWithPosts = await prisma.user.findUnique({
where: {
id: 1,
},
include: {
posts: {
orderBy: {
title: 'desc',
},
select: {
title: true,
published: true,
},
},
},
});
按 enum 排序
以下按 role(一個 enum)排序所有 User 記錄
const sort = await prisma.user.findMany({
orderBy: {
role: 'desc',
},
select: {
email: true,
role: true,
},
});
orderBy 的生成型別
以下示例演示瞭如何將 validator 與 orderBy 一起使用
UserOrderByInputconst orderEmailsByDescending = Prisma.validator<Prisma.UserOrderByInput>()({
email: 'desc',
});
distinct
從 findMany 或 findFirst 中去除記錄列表的重複項。另請參閱:聚合、分組和彙總
示例
在單個欄位上選擇 distinct
以下示例返回所有不同的 city 欄位,並且只選擇 city 和 country 欄位
const distinctCities = await prisma.user.findMany({
select: {
city: true,
country: true,
},
distinct: ['city'],
});
[
{ city: 'Paris', country: 'France' },
{ city: 'Lyon', country: 'France' },
];
在多個欄位上選擇 distinct
以下示例返回所有不同的 city 和 country 欄位組合,並且只選擇 city 和 country 欄位
const distinctCitiesAndCountries = await prisma.user.findMany({
select: {
city: true,
country: true,
},
distinct: ['city', 'country'],
});
[
{ city: 'Paris', country: 'France' },
{ city: 'Paris', country: 'Denmark' },
{ city: 'Lyon', country: 'France' },
];
請注意,除了“法國巴黎”之外,現在還有“丹麥巴黎”
結合過濾器選擇 distinct
以下示例返回所有不同的 city 和 country 欄位組合,其中使用者電子郵件包含 "prisma.io",並且只選擇 city 和 country 欄位
const distinctCitiesAndCountries = await prisma.user.findMany({
where: {
email: {
contains: 'prisma.io',
},
},
select: {
city: true,
country: true,
},
distinct: ['city', 'country'],
});
nativeDistinct
在您的 Prisma schema 中啟用 nativeDistinct 會將 distinct 操作推送到資料庫層(如果支援)。這可以顯著提高效能。但是,請注意
- 某些資料庫可能不完全支援特定欄位組合上的 DISTINCT。
- 不同提供商的行為可能有所不同。
要啟用 nativeDistinct
generator client {
provider = "prisma-client-js"
previewFeatures = ["nativeDistinct"]
}
有關詳細資訊,請參閱預覽功能。
巢狀查詢
create
巢狀 create 查詢會將一條或一組新的相關記錄新增到父記錄。請參閱:處理關係
備註
- 當您
create()(prisma.user.create(...)) 一個新的父記錄或update()(prisma.user.update(...)) 一個現有父記錄時,create可作為巢狀查詢使用。 - 您可以使用巢狀的
create或 巢狀的createMany來建立多個相關記錄。如果需要skipDuplicates查詢選項,您應該使用createMany。
示例
建立包含新 Profile 記錄的新 User 記錄
const user = await prisma.user.create({
data: {
email: 'alice@prisma.io',
profile: {
create: { bio: 'Hello World' },
},
},
});
建立包含新 User 記錄的新 Profile 記錄
const user = await prisma.profile.create({
data: {
bio: 'Hello World',
user: {
create: { email: 'alice@prisma.io' },
},
},
})
建立包含新 Post 記錄的新 User 記錄
const user = await prisma.user.create({
data: {
email: 'alice@prisma.io',
posts: {
create: { title: 'Hello World' },
},
},
});
建立包含兩條新 Post 記錄的新 User 記錄
因為這是一對多關係,您還可以透過向 create 傳遞一個數組來一次性建立多個 Post 記錄
const user = await prisma.user.create({
data: {
email: 'alice@prisma.io',
posts: {
create: [
{
title: 'This is my first post',
},
{
title: 'Here comes a second post',
},
],
},
},
});
注意:您也可以使用巢狀的 createMany 來實現相同的結果。
透過建立新的 Profile 記錄來更新現有 User 記錄
const user = await prisma.user.update({
where: { email: 'alice@prisma.io' },
data: {
profile: {
create: { bio: 'Hello World' },
},
},
});
透過建立新的 Post 記錄來更新現有 User 記錄
const user = await prisma.user.update({
where: { email: 'alice@prisma.io' },
data: {
posts: {
create: { title: 'Hello World' },
},
},
})
createMany
巢狀 createMany 查詢會將一組新的記錄新增到父記錄。請參閱:處理關係
備註
- 當您
create()(prisma.user.create(...)) 一個新的父記錄或update()(prisma.user.update(...)) 一個現有父記錄時,createMany可作為巢狀查詢使用。- 在一對多關係的上下文中可用 — 例如,您可以
prisma.user.create(...)一個使用者並使用巢狀的createMany來建立多個帖子(帖子有一個使用者)。 - 在多對多關係的上下文中不可用 — 例如,您不能
prisma.post.create(...)一個帖子並使用巢狀的createMany來建立類別(許多帖子有許多類別)。
- 在一對多關係的上下文中可用 — 例如,您可以
- 您不能再巢狀一個
create或createMany。 - 允許直接設定外部索引鍵 — 例如,設定帖子的
categoryId。 - 從 Prisma ORM 5.12.0 版本開始,SQLite 支援巢狀的
createMany。 - 您可以使用巢狀的
create或 巢狀的createMany來建立多個相關記錄 - 如果您不需要skipDuplicates查詢選項,您可能應該使用create。
選項
| 名稱 | 型別 | 必需 | 描述 |
|---|---|---|---|
data | Enumerable<UserCreateManyInput> | 是 | 將所有模型欄位包裝在型別中,以便在建立新記錄時提供它們。在資料模型中標記為可選或具有預設值的欄位是可選的。 |
skipDuplicates? | 布林 | 否 | 不插入具有已存在唯一欄位或 ID 欄位的記錄。僅受支援 ON CONFLICT DO NOTHING 的資料庫支援。這不包括 MongoDB 和 SQLServer |
示例
更新 User 和多個新的相關 Post 記錄
const user = await prisma.user.update({
where: {
id: 9,
},
data: {
name: 'Elliott',
posts: {
createMany: {
data: [{ title: 'My first post' }, { title: 'My second post' }],
},
},
},
});
set
set 覆蓋關係的當前值 — 例如,用不同的列表替換 Post 記錄列表。請參閱:處理關係
示例
透過斷開任何先前的 Post 記錄並連線兩條其他現有記錄來更新現有 User 記錄
const user = await prisma.user.update({
where: { email: 'alice@prisma.io' },
data: {
posts: {
set: [{ id: 32 }, { id: 42 }],
},
},
});
connect
巢狀 connect 查詢透過指定 ID 或唯一識別符號將記錄連線到現有相關記錄。請參閱:處理關係
備註
-
當您建立新的父記錄或更新現有父記錄時,
connect可作為巢狀查詢使用。 -
如果相關記錄不存在,Prisma Client 將丟擲異常
The required connected records were not found. Expected 1 records to be connected, found 0. -
當同時使用
set和connect時,它們的應用順序會顯著影響結果。如果在connect之前使用set,則連線的記錄將只反映connect操作建立的最終狀態,因為set會在connect建立新連線之前清除所有現有連線。反之,如果在set之前應用connect,則set操作將透過清除所有已連線的記錄並將其替換為自身指定的狀態來覆蓋connect操作。
示例
建立新的 Profile 記錄並透過唯一欄位將其連線到現有 User 記錄
const user = await prisma.profile.create({
data: {
bio: 'Hello World',
user: {
connect: { email: 'alice@prisma.io' },
},
},
});
建立新的 Profile 記錄並透過 ID 欄位將其連線到現有 User 記錄
const user = await prisma.profile.create({
data: {
bio: 'Hello World',
user: {
connect: { id: 42 }, // sets userId of Profile record
},
},
});
在 2.11.0 及更高版本中,您可以直接設定外部索引鍵
const user = await prisma.profile.create({
data: {
bio: 'Hello World',
userId: 42,
},
});
但是,您不能在同一查詢中同時使用直接方法和 connect 方法。有關詳細資訊,請參閱此問題評論。
建立新的 Post 記錄並將其連線到現有 User 記錄
const user = await prisma.post.create({
data: {
title: 'Hello World',
author: {
connect: { email: 'alice@prisma.io' },
},
},
});
透過連線到現有 Profile 記錄來更新現有 User 記錄
const user = await prisma.user.update({
where: { email: 'alice@prisma.io' },
data: {
profile: {
connect: { id: 24 },
},
},
});
透過連線到兩條現有 Post 記錄來更新現有 User 記錄
const user = await prisma.user.update({
where: { email: 'alice@prisma.io' },
data: {
posts: {
connect: [{ id: 24 }, { id: 42 }],
},
},
});
connectOrCreate
connectOrCreate 要麼 透過 ID 或唯一識別符號將記錄連線到現有相關記錄,要麼 在記錄不存在時建立新的相關記錄。請參閱:處理關係
備註
-
同時執行的多個
connectOrCreate查詢(作為併發事務)可能導致競態條件。考慮以下示例,其中兩個查詢試圖同時connectOrCreate名為computing的部落格文章標籤(標籤名稱必須是唯一的)- 查詢 A
- 查詢 B
const createPost = await prisma.post.create({
data: {
title: 'How to create a compiler',
content: '...',
author: {
connect: {
id: 9,
},
},
tags: {
connectOrCreate: {
create: {
name: 'computing',
},
where: {
name: 'computing',
},
},
},
},
})const createPost = await prisma.post.create({
data: {
title: 'How to handle schema drift in production',
content: '...',
author: {
connect: {
id: 15,
},
},
tags: {
connectOrCreate: {
create: {
name: 'computing',
},
where: {
name: 'computing',
},
},
},
},
})如果查詢 A 和查詢 B 以以下方式重疊,則查詢 A 會導致異常
查詢 A (失敗 ❌) 查詢 B (成功 ✅) 查詢到達伺服器,開始事務 A 查詢到達伺服器,開始事務 B 查詢 tagName等於computing的記錄,未找到記錄查詢 tagName等於computing的記錄,未找到記錄建立 tagName等於computing的記錄並連線建立 tagName等於computing的記錄唯一性衝突,記錄已被事務 B 建立 為了解決這種情況,我們建議捕獲唯一性衝突異常(
PrismaClientKnownRequestError,錯誤程式碼P2002)並重試失敗的查詢。
示例
建立新的 Profile 記錄,然後將其連線到現有 User 記錄或建立新的 User
以下示例
- 建立一個
Profile - 嘗試將 profile 連線到電子郵件地址為
alice@prisma.io的User - 如果匹配的使用者不存在,則建立一個新使用者
const user = await prisma.profile.create({
data: {
bio: 'The coolest Alice on the planet',
user: {
connectOrCreate: {
where: { email: 'alice@prisma.io' },
create: { email: 'alice@prisma.io'}
},
},
})
建立新的 Post 記錄並將其連線到現有 User 記錄,或建立新的 User
const user = await prisma.post.create({
data: {
title: 'Hello World',
author: {
connectOrCreate: {
where: { email: 'alice@prisma.io' },
create: { email: 'alice@prisma.io' },
},
},
},
});
透過連線到現有 Profile 記錄或建立新的 Profile 記錄來更新現有 User 記錄
以下示例
- 嘗試將使用者連線到
id為20的Profile - 如果匹配的 profile 不存在,則建立一個新 profile
const updateUser = await prisma.user.update({
where: { email: 'alice@prisma.io' },
data: {
profile: {
connectOrCreate: {
where: { id: 20 },
create: {
bio: 'The coolest Alice in town',
},
},
},
},
});
透過連線到兩條現有 Post 記錄或建立兩條新 Post 記錄來更新現有 User 記錄
const user = await prisma.user.update({
where: { email: 'alice@prisma.io' },
data: {
posts: {
connectOrCreate: [
{
where: { id: 32 },
create: { title: 'This is my first post' },
},
{
where: { id: 19 },
create: { title: 'This is my second post' },
},
],
},
},
});
disconnect
巢狀 disconnect 查詢會中斷父記錄和相關記錄之間的連線,但不會刪除任何記錄。請參閱:處理關係
備註
-
disconnect僅在關係是可選時可用。 -
如果您嘗試斷開的關係不存在
-
(在 2.21.0 及更高版本中),該操作不做任何事情
-
(在 2.21.0 之前)如果提供的 ID 或唯一識別符號未連線,Prisma Client 將丟擲異常
The records for relation `PostToUser` between the `User` and `Post` models are not connected.
-
示例
透過斷開與 Profile 記錄的連線來更新現有 User 記錄
const user = await prisma.user.update({
where: { email: 'bob@prisma.io' },
data: {
profile: {
disconnect: true,
},
},
});
透過斷開與兩條 Post 記錄的連線來更新現有 User 記錄
const user = await prisma.user.update({
where: { email: 'alice@prisma.io' },
data: {
posts: {
disconnect: [{ id: 44 }, { id: 46 }],
},
},
});
update
巢狀的 update 查詢會更新一個或多個相關記錄,其中父記錄的 ID 為 n。請參閱:處理關係
備註
-
巢狀的
update查詢僅在頂級update查詢的上下文中可用(例如,prisma.user.update(...))。 -
如果父記錄不存在,Prisma Client 將丟擲異常
AssertionError("Expected a valid parent ID to be present for nested update to-one case.") -
如果您想要更新的相關記錄不存在,Prisma Client 將丟擲異常
AssertionError("Expected a valid parent ID to be present for nested update to-one case.")
示例
透過更新所連線的 Profile 記錄來更新現有 User 記錄
const user = await prisma.user.update({
where: { email: 'alice@prisma.io' },
data: {
profile: {
update: { bio: 'Hello World' },
},
},
});
透過更新所連線的兩條 Post 記錄來更新現有 User 記錄
const user = await prisma.user.update({
where: { email: 'alice@prisma.io' },
data: {
posts: {
update: [
{
data: { published: true },
where: { id: 32 },
},
{
data: { published: true },
where: { id: 23 },
},
],
},
},
});
upsert
本節介紹 update() 中巢狀 upsert 的用法。要了解 upsert() 操作,請參考連結的文件。
巢狀的 upsert 查詢會在相關記錄存在時更新它,或者在不存在時建立新的相關記錄。
示例
透過更新現有 User 記錄所連線的 Profile 記錄或建立新記錄來更新現有 User 記錄(upsert)
const user = await prisma.user.update({
where: { email: 'alice@prisma.io' },
data: {
profile: {
upsert: {
create: { bio: 'Hello World' },
update: { bio: 'Hello World' },
},
},
},
});
透過更新現有 User 記錄所連線的兩個 Post 記錄或建立新記錄來更新現有 User 記錄(upsert)
const user = await prisma.user.update({
where: { email: 'alice@prisma.io' },
data: {
posts: {
upsert: [
{
create: { title: 'This is my first post' },
update: { title: 'This is my first post' },
where: { id: 32 },
},
{
create: { title: 'This is my second post' },
update: { title: 'This is my second post' },
where: { id: 23 },
},
],
},
},
});
delete
巢狀的 delete 查詢會刪除相關記錄。父記錄不會被刪除。
備註
delete僅在關係可選時可用。
示例
透過刪除現有 User 記錄所連線的 Profile 記錄來更新現有 User 記錄
const user = await prisma.user.update({
where: { email: 'alice@prisma.io' },
data: {
profile: {
delete: true,
},
},
});
透過刪除現有 User 記錄所連線的兩個 Post 記錄來更新現有 User 記錄
const user = await prisma.user.update({
where: { email: 'alice@prisma.io' },
data: {
posts: {
delete: [{ id: 34 }, { id: 36 }],
},
},
});
updateMany
巢狀的 updateMany 會更新相關記錄列表並支援篩選——例如,您可以更新使用者的未釋出帖子。
示例
更新屬於特定使用者的所有未釋出帖子
const result = await prisma.user.update({
where: {
id: 2,
},
data: {
posts: {
updateMany: {
where: {
published: false,
},
data: {
likes: 0,
},
},
},
},
});
deleteMany
巢狀的 deleteMany 會刪除相關記錄並支援篩選。例如,您可以在更新該使用者的其他屬性時刪除該使用者的帖子。
示例
作為更新的一部分,刪除屬於特定使用者的所有帖子
const result = await prisma.user.update({
where: {
id: 2,
},
data: {
name: 'Updated name',
posts: {
deleteMany: {},
},
},
});
篩選條件和運算子
equals
值等於 n。
示例
返回所有 name 等於 "Eleanor" 的使用者
const result = await prisma.user.findMany({
where: {
name: {
equals: 'Eleanor',
},
},
});
您也可以省略 equals
const result = await prisma.user.findMany({
where: {
name: 'Eleanor',
},
});
返回所有數量低於“警告數量”閾值的產品
此示例比較了同一模型的欄位,該功能從版本 4.3.0 開始可用。
const productsWithLowQuantity = await prisma.product.findMany({
where: {
quantity: {
lte: prisma.product.fields.warnQuantity
},
},
});
返回所有收藏顏色為藍色和綠色的使用者
此示例查詢將其 favoriteColors 欄位設定為 ['blue', 'green'] 的使用者。
請注意,當使用 equals 時,元素的順序很重要。也就是說 ['blue', 'green'] 不等於 ['green', 'blue']
const favoriteColorFriends = await prisma.user.findMany({
where: {
favoriteColors: {
equals: ['blue', 'green'],
},
},
});
not
值不等於 n。
示例
返回所有 name 不等於 "Eleanor" 的使用者
const result = await prisma.user.findMany({
where: {
name: {
not: 'Eleanor',
},
},
});
not 將返回所有不匹配給定值的專案。但是,如果列可為空,則不會返回 NULL 值。如果您需要返回 null 值,請使用 OR 運算子以包含 NULL 值。
返回所有 name 不等於 "Eleanor" 的使用者,包括 name 為 NULL 的使用者
await prisma.user.findMany({
where: {
OR: [
{ name: { not: 'Eleanor' } },
{ name: null }
]
}
})
in
值 n 存在於列表中。
null 值不會被返回。例如,如果您組合使用 in 和 NOT 來返回名稱不在列表中的使用者,則不會返回名稱為 null 值的使用者。
示例
獲取 id 可以在以下列表中找到的 User 記錄:[22, 91, 14, 2, 5]
const getUser = await prisma.user.findMany({
where: {
id: { in: [22, 91, 14, 2, 5] },
},
});
獲取 name 可以在以下列表中找到的 User 記錄:['Saqui', 'Clementine', 'Bob']
const getUser = await prisma.user.findMany({
where: {
name: { in: ['Saqui', 'Clementine', 'Bob'] },
},
});
獲取 name 不在列表中的 User 記錄
以下示例結合了 in 和 NOT。您也可以使用 notIn。
const getUser = await prisma.user.findMany({
where: {
NOT: {
name: { in: ['Saqui', 'Clementine', 'Bob'] },
},
},
});
獲取至少一個 Post 包含至少一個指定 Category 的 User 記錄
const getUser = await prisma.user.findMany({
where: {
// Find users where..
posts: {
some: {
// ..at least one (some) posts..
categories: {
some: {
// .. have at least one category ..
name: {
in: ['Food', 'Introductions'], // .. with a name that matches one of the following.
},
},
},
},
},
},
});
notIn
值 n 不存在於列表中。
備註
null值不會被返回。
示例
獲取 id 不在以下列表中的 User 記錄:[22, 91, 14, 2, 5]
const getUser = await prisma.user.findMany({
where: {
id: { notIn: [22, 91, 14, 2, 5] },
},
});
lt
值 n 小於 x。
示例
獲取所有 likes 小於 9 的 Post 記錄
const getPosts = await prisma.post.findMany({
where: {
likes: {
lt: 9,
},
},
});
lte
值 n 小於或等於 x。
示例
獲取所有 likes 小於或等於 9 的 Post 記錄
const getPosts = await prisma.post.findMany({
where: {
likes: {
lte: 9,
},
},
});
gt
值 n 大於 x。
示例
獲取所有 likes 大於 9 的 Post 記錄
const getPosts = await prisma.post.findMany({
where: {
likes: {
gt: 9,
},
},
});
gte
值 n 大於或等於 x。
示例
獲取所有 likes 大於或等於 9 的 Post 記錄
const getPosts = await prisma.post.findMany({
where: {
likes: {
gte: 9,
},
},
});
示例
獲取所有 date_created 晚於 2020 年 3 月 19 日的 Post 記錄
const result = await prisma.post.findMany({
where: {
date_created: {
gte: new Date('2020-03-19T14:21:00+0200') /* Includes time offset for UTC */,
},
},
});
contains
值 n 包含 x。
示例
統計所有 content 包含 databases 的 Post 記錄
const result = await prisma.post.count({
where: {
content: {
contains: 'databases',
},
},
});
統計所有 content 不包含 databases 的 Post 記錄
const result = await prisma.post.count({
where: {
NOT: {
content: {
contains: 'databases',
},
},
},
});
search
使用全文搜尋在 String 欄位中進行搜尋。
對於 PostgreSQL,此功能仍處於預覽階段。要使用它,請啟用 fullTextSearchPostgres 功能標誌。
示例
查詢所有標題包含 cat 或 dog 的帖子。
const result = await prisma.post.findMany({
where: {
title: {
search: 'cat | dog',
},
},
});
查詢所有標題包含 cat 和 dog 的帖子。
const result = await prisma.post.findMany({
where: {
title: {
search: 'cat & dog',
},
},
});
查詢所有標題不包含 cat 的帖子。
const result = await prisma.post.findMany({
where: {
title: {
search: '!cat',
},
},
});
mode
備註
- 僅 PostgreSQL 和 MongoDB 聯結器支援
示例
獲取所有 title 包含 prisma(不區分大小寫)的 Post 記錄
const result = await prisma.post.findMany({
where: {
title: {
contains: 'prisma',
mode: 'insensitive',
},
},
});
startsWith
示例
獲取所有 title 以 Pr 開頭(例如 Prisma)的 Post 記錄
const result = await prisma.post.findMany({
where: {
title: {
startsWith: 'Pr',
},
},
});
endsWith
獲取所有 email 以 prisma.io 結尾的 User 記錄
const result = await prisma.user.findMany({
where: {
email: {
endsWith: 'prisma.io',
},
},
});
AND
所有條件必須返回 true。或者,將物件列表傳遞到 where 子句中——不需要 AND 運算子。
示例
獲取所有 content 欄位包含 Prisma 且 published 為 false 的 Post 記錄
const result = await prisma.post.findMany({
where: {
AND: [
{
content: {
contains: 'Prisma',
},
},
{
published: {
equals: false,
},
},
],
},
});
獲取所有 content 欄位包含 Prisma 且 published 為 false 的 Post 記錄(無 AND)
以下格式返回與上一個示例相同的結果,不帶 AND 運算子
const result = await prisma.post.findMany({
where: {
content: {
contains: 'Prisma',
},
published: {
equals: false,
},
},
});
獲取所有 title 欄位包含 Prisma 或 databases 且 published 為 false 的 Post 記錄
以下示例結合了 OR 和 AND
const result = await prisma.post.findMany({
where: {
OR: [
{
title: {
contains: 'Prisma',
},
},
{
title: {
contains: 'databases',
},
},
],
AND: {
published: false,
},
},
});
OR
一個或多個條件必須返回 true。
示例
獲取所有 title 欄位包含 Prisma 或 databases 的 Post 記錄
const result = await prisma.post.findMany({
where: {
OR: [
{
title: {
contains: 'Prisma',
},
},
{
title: {
contains: 'databases',
},
},
],
},
});
獲取所有 title 欄位包含 Prisma 或 databases 但不包含 SQL 的 Post 記錄
以下示例結合了 OR 和 NOT
const result = await prisma.post.findMany({
where: {
OR: [
{
title: {
contains: 'Prisma',
},
},
{
title: {
contains: 'databases',
},
},
],
NOT: {
title: {
contains: 'SQL',
},
},
},
});
獲取所有 title 欄位包含 Prisma 或 databases 且 published 為 false 的 Post 記錄
以下示例結合了 OR 和 AND
const result = await prisma.post.findMany({
where: {
OR: [
{
title: {
contains: 'Prisma',
},
},
{
title: {
contains: 'databases',
},
},
],
AND: {
published: false,
},
},
});
NOT
所有條件必須返回 false。
示例
獲取所有 title 不包含 SQL 的 Post 記錄
const result = await prisma.post.findMany({
where: {
NOT: {
title: {
contains: 'SQL',
},
},
},
});
獲取所有 title 欄位包含 Prisma 或 databases 但不包含 SQL,並且相關 User 記錄的電子郵件地址不包含 sarah 的 Post 記錄
const result = await prisma.post.findMany({
where: {
OR: [
{
title: {
contains: 'Prisma',
},
},
{
title: {
contains: 'databases',
},
},
],
NOT: {
title: {
contains: 'SQL',
},
},
user: {
NOT: {
email: {
contains: 'sarah',
},
},
},
},
include: {
user: true,
},
});
關係篩選器
some
返回所有一個或多個(“some”)相關記錄匹配篩選條件的記錄。
備註
- 您可以在不帶引數的情況下使用
some來返回所有至少有一個關係的記錄
示例
獲取所有 User 記錄,其中一些帖子提到了 Prisma
const result = await prisma.user.findMany({
where: {
post: {
some: {
content: {
contains: "Prisma"
}
}
}
}
}
every
返回所有所有(“every”)相關記錄匹配篩選條件的記錄。
示例
獲取所有 User 記錄,其中所有帖子都已釋出
const result = await prisma.user.findMany({
where: {
post: {
every: {
published: true
},
}
}
}
none
返回所有零相關記錄匹配篩選條件的記錄。
備註
- 您可以在不帶引數的情況下使用
none來返回所有沒有關係的記錄
示例
獲取所有零帖子的 User 記錄
const result = await prisma.user.findMany({
where: {
post: {
none: {} // User has no posts
}
}
}
獲取所有零已釋出帖子的 User 記錄
const result = await prisma.user.findMany({
where: {
post: {
none: {
published: true
}
}
}
}
is
返回所有相關記錄匹配篩選條件的記錄(例如,使用者的名稱 is Bob)。
示例
獲取所有使用者名稱為 "Bob" 的 Post 記錄
const result = await prisma.post.findMany({
where: {
user: {
is: {
name: "Bob"
},
}
}
}
isNot
返回所有相關記錄不匹配篩選條件的記錄(例如,使用者的名稱 isNot Bob)。
示例
獲取所有使用者名稱不是 "Bob" 的 Post 記錄
const result = await prisma.post.findMany({
where: {
user: {
isNot: {
name: "Bob"
},
}
}
}
標量列表方法
set
使用 set 覆蓋標量列表欄位的值。
備註
-
set是可選的——您可以直接設定值tags: ['computers', 'books'];
示例
將 tags 的值設定為字串值列表
const setTags = await prisma.post.update({
where: {
id: 9,
},
data: {
tags: {
set: ['computing', 'books'],
},
},
});
將 tags 設定為值列表,不使用 set 關鍵字
const setTags = await prisma.post.update({
where: {
id: 9,
},
data: {
tags: ['computing', 'books'],
},
});
將 tags 的值設定為單個字串值
const setTags = await prisma.post.update({
where: {
id: 9,
},
data: {
tags: {
set: 'computing',
},
},
});
push
push 在版本 2.20.0 及更高版本中可用。使用 push 將一個值或多個值新增到標量列表欄位中。
備註
- 僅適用於 PostgreSQL 和 MongoDB。
- 您可以推送一個值列表或單個值。
示例
向 tags 列表中新增一個 computing 項
const addTag = await prisma.post.update({
where: {
id: 9,
},
data: {
tags: {
push: 'computing',
},
},
});
const addTag = await prisma.post.update({
where: {
id: 9,
},
data: {
tags: {
push: ['computing', 'genetics'],
},
},
});
unset
此方法僅在 MongoDB 版本的 3.11.1 及更高版本中可用。
使用 unset 來取消設定標量列表的值。與 set: null 不同,unset 會完全刪除該列表。
示例
取消設定 tags 的值
const setTags = await prisma.post.update({
where: {
id: 9,
},
data: {
tags: {
unset: true,
},
},
});
標量列表篩選器
標量列表篩選器允許您按列表/陣列欄位的內容進行篩選。
備註
- 標量列表/陣列篩選器忽略
NULL值。使用isEmpty或NOT不會返回具有NULL值列表/陣列的記錄,並且{ equals: null }會導致錯誤。
has
給定值存在於列表中。
示例
以下查詢返回所有 tags 列表包含 "databases" 的 Post 記錄
const posts = await client.post.findMany({
where: {
tags: {
has: 'databases',
},
},
});
以下查詢返回所有 tags 列表不包含 "databases" 的 Post 記錄
const posts = await client.post.findMany({
where: {
NOT: {
tags: {
has: 'databases',
},
},
},
});
hasEvery
列表中存在所有值。
示例
以下查詢返回所有 tags 列表至少包含 "databases" 和 "typescript" 的 Post 記錄
const posts = await prisma.post.findMany({
where: {
tags: {
hasEvery: ['databases', 'typescript'],
},
},
});
hasSome
列表中至少存在一個值。
示例
以下查詢返回所有 tags 列表包含 "databases" 或 "typescript" 的 Post 記錄
const posts = await prisma.post.findMany({
where: {
tags: {
hasSome: ['databases', 'typescript'],
},
},
});
isEmpty
列表為空。
示例
以下查詢返回所有沒有標籤的 Post 記錄
const posts = await prisma.post.findMany({
where: {
tags: {
isEmpty: true,
},
},
});
isSet
此篩選器僅在 MongoDB 版本的 3.11.1 及更高版本中可用。
篩選列表以僅包含已設定(設定為值或顯式設定為 null)的結果。將此篩選器設定為 true 將排除根本未設定的未定義結果。
示例
以下查詢返回所有 tags 已設定為 null 或值的 Post 記錄
const posts = await prisma.post.findMany({
where: {
tags: {
isSet: true,
},
},
});
equals
列表精確匹配給定值。
示例
以下查詢返回所有 tags 列表僅包含 "databases" 和 "typescript" 的 Post 記錄
const posts = await prisma.post.findMany({
where: {
tags: {
equals: ['databases', 'typescript'],
},
},
});
複合型別方法
僅在 Prisma 3.10.0 及更高版本中適用於 MongoDB。
複合型別方法允許您建立、更新和刪除複合型別。
set
使用 set 覆蓋複合型別的值。
備註
set關鍵字是可選的——您可以直接設定值photos: [
{ height: 100, width: 200, url: '1.jpg' },
{ height: 100, width: 200, url: '2.jpg' },
];
示例
在新 order 中設定 shippingAddress 複合型別
const order = await prisma.order.create({
data: {
// Normal relation
product: { connect: { id: 'some-object-id' } },
color: 'Red',
size: 'Large',
// Composite type
shippingAddress: {
set: {
street: '1084 Candycane Lane',
city: 'Silverlake',
zip: '84323',
},
},
},
});
將可選複合型別設定為 null
const order = await prisma.order.create({
data: {
// Embedded optional type, set to null
billingAddress: {
set: null,
},
},
});
unset
使用 unset 來取消設定複合型別的值。與 set: null 不同,這會從 MongoDB 文件中完全刪除該欄位。
示例
從 order 中刪除 billingAddress
const order = await prisma.order.update({
where: {
id: 'some-object-id',
},
data: {
billingAddress: {
// Unset the billing address
// Removes "billingAddress" field from order
unset: true,
},
},
});
update
使用 update 更新必需複合型別中的欄位。
備註
update 方法不能用於可選型別。請改用 upsert
示例
更新 shippingAddress 複合型別的郵政編碼欄位
const order = await prisma.order.update({
where: {
id: 'some-object-id',
},
data: {
shippingAddress: {
// Update just the zip field
update: {
zip: '41232',
},
},
},
});
upsert
使用 upsert 更新現有可選複合型別(如果存在),否則設定複合型別。
備註
upsert 方法不能用於必需型別。請改用 update
示例
如果不存在,則建立新的 billingAddress,否則更新它
const order = await prisma.order.update({
where: {
id: 'some-object-id',
},
data: {
billingAddress: {
// Create the address if it doesn't exist,
// otherwise update it
upsert: {
set: {
street: '1084 Candycane Lane',
city: 'Silverlake',
zip: '84323',
},
update: {
zip: '84323',
},
},
},
},
});
push
使用 push 將值推送到複合型別列表的末尾。
示例
將新照片新增到 photos 列表
const product = prisma.product.update({
where: {
id: 10,
},
data: {
photos: {
// Push a photo to the end of the photos list
push: [{ height: 100, width: 200, url: '1.jpg' }],
},
},
});
複合型別篩選器
僅在 Prisma 3.11.0 及更高版本中適用於 MongoDB。
複合型別篩選器允許您篩選複合型別的內容。
equals
使用 equals 透過匹配複合型別或複合型別列表來篩選結果。要求複合型別的所有必需欄位都匹配。
備註
當匹配可選欄位時,您需要區分文件中未定義的(缺失的)欄位和已顯式設定為 null 的欄位
- 如果您省略可選欄位,它將匹配未定義的欄位,但不會匹配已設定為
null的欄位 - 如果您使用
equals: { ... exampleField: null ... }篩選可選欄位的null值,那麼它將僅匹配該欄位已設定為null的文件,而不匹配未定義的欄位
使用 equals 時,欄位和列表的順序很重要
- 對於欄位,
{ "a": "1", "b": "2" }和{ "b": "2", "a": "1" }不被視為相等 - 對於列表,
[ { "a": 1 }, { "a": 2 } ]和[ { "a": 2 }, { "a": 1 } ]不被視為相等
示例
查詢與給定 shippingAddress 完全匹配的訂單
const orders = await prisma.order.findMany({
where: {
shippingAddress: {
equals: {
street: '555 Candy Cane Lane',
city: 'Wonderland',
zip: '52337',
},
},
},
});
查詢照片與所有給定 url 列表匹配的產品
const product = prisma.product.findMany({
where: {
equals: {
photos: [{ url: '1.jpg' }, { url: '2.jpg' }],
},
},
});
is
使用 is 透過匹配複合型別中的特定欄位來篩選結果。
示例
查詢 shippingAddress 匹配給定街道名稱的訂單
const orders = await prisma.order.findMany({
where: {
shippingAddress: {
is: {
street: '555 Candy Cane Lane',
},
},
},
});
isNot
使用 isNot 篩選複合型別欄位不匹配的結果。
示例
查詢 shippingAddress 不匹配給定郵政編碼的訂單
const orders = await prisma.order.findMany({
where: {
shippingAddress: {
isNot: {
zip: '52337',
},
},
},
});
isEmpty
使用 isEmpty 篩選複合型別的空列表結果。
示例
查詢沒有照片的產品
const product = prisma.product.findMany({
where: {
photos: {
isEmpty: true,
},
},
});
every
使用 every 篩選複合型別列表,其中列表中的每個專案都匹配條件
示例
查詢第一款所有照片高度都為 200 的產品
const product = await prisma.product.findFirst({
where: {
photos: {
every: {
height: 200,
}
}
},
})
some
使用 some 篩選複合型別列表,其中列表中一個或多個專案匹配條件。
示例
查詢第一款一個或多個照片 url 為 2.jpg 的產品
const product = await prisma.product.findFirst({
where: {
photos: {
some: {
url: "2.jpg",
}
}
},
})
none
使用 none 篩選複合型別列表,其中列表中沒有專案匹配條件。
示例
查詢第一款沒有照片 url 為 2.jpg 的產品
const product = await prisma.product.findFirst({
where: {
photos: {
none: {
url: "2.jpg",
}
}
},
})
原子數字運算
更新時的原子操作適用於數字欄位型別(Float 和 Int)。此功能允許您根據欄位的當前值(例如減去或除以)更新欄位,而不會冒競態條件的風險。
概述:競態條件
當需要按順序完成兩個或更多操作才能完成任務時,就會發生競態條件。在以下示例中,兩個客戶端嘗試將同一欄位(postCount)增加一
| 客戶端 | 操作 | 值 |
|---|---|---|
| 客戶端 1 | 獲取欄位值 | 21 |
| 客戶端 2 | 獲取欄位值 | 21 |
| 客戶端 2 | 設定欄位值 | 22 |
| 客戶端 1 | 設定欄位值 | 22 ✘ |
值應該是 23,但兩個客戶端沒有按順序讀寫 postCount 欄位。更新時的原子操作將讀寫組合成一個操作,從而防止競態條件
| 客戶端 | 操作 | 值 |
|---|---|---|
| 客戶端 1 | 獲取並設定欄位值 | 21 → 22 |
| 客戶端 2 | 獲取並設定欄位值 | 22 → 23 ✔ |
運算子
| 選項 | 描述 |
|---|---|
increment | 將 n 新增到當前值。 |
decrement | 從當前值中減去 n。 |
multiply | 將當前值乘以 n。 |
divide | 將當前值除以 n。 |
set | 設定當前欄位值。與 { myField : n } 相同。 |
備註
- 每次查詢,每個欄位只能執行一個原子更新。
- 如果欄位為
null,它不會被increment、decrement、multiply或divide更新。
示例
將所有 Post 記錄的所有 view 和 likes 欄位增加 1
const updatePosts = await prisma.post.updateMany({
data: {
views: {
increment: 1,
},
likes: {
increment: 1,
},
},
});
將所有 Post 記錄的所有 views 欄位設定為 0
const updatePosts = await prisma.post.updateMany({
data: {
views: {
set: 0,
},
},
});
也可以寫成
const updatePosts = await prisma.post.updateMany({
data: {
views: 0,
},
});
Json 篩選器
有關用例和高階示例,請參閱:使用 Json 欄位。
由PostgreSQL和MySQL支援,path 選項的語法不同。PostgreSQL 不支援篩選陣列中的物件鍵值。
本節中的示例假定 pet 欄位的值是
{
"favorites": {
"catBreed": "Turkish van",
"dogBreed": "Rottweiler",
"sanctuaries": ["RSPCA", "Alley Cat Allies"],
"treats": [
{ "name": "Dreamies", "manufacturer": "Mars Inc" },
{ "name": "Treatos", "manufacturer": "The Dog People" }
]
},
"fostered": {
"cats": ["Bob", "Alice", "Svetlana the Magnificent", "Queenie"]
},
"owned": {
"cats": ["Elliott"]
}
}
備註
Json篩選器的實現在不同資料庫聯結器之間有所不同- PostgreSQL 中的篩選器區分大小寫,並且尚不支援
mode
path
path 表示特定鍵的位置。以下查詢返回所有巢狀 favourites > dogBreed 鍵等於 "Rottweiler" 的使用者。
- PostgreSQL
- MySQL
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: ['favorites', 'dogBreed'],
equals: 'Rottweiler',
},
},
});
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: '$.favorites.dogBreed',
equals: 'Rottweiler',
},
},
});
以下查詢返回所有巢狀 owned > cats 陣列包含 "Elliott" 的使用者。
- PostgreSQL
- MySQL
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: ['owned', 'cats'],
array_contains: ['Elliott'],
},
},
});
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: '$.owned.cats',
array_contains: 'Elliott',
},
},
});
篩選陣列內部物件的鍵值(如下)僅由 MySQL 聯結器支援。
以下查詢返回所有巢狀 favorites > treats 陣列包含 name 值為 "Dreamies" 的物件的使用者
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: '$.favorites.treats[*].name',
array_contains: 'Dreamies',
},
},
});
string_contains
以下查詢返回所有巢狀 favorites > catBreed 鍵值包含 "Van" 的使用者
- PostgreSQL
- MySQL
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: ['favorites', 'catBreed'],
string_contains: 'Van',
},
},
});
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: '$.favorites.catBreed',
string_contains: 'Van',
},
},
});
string_starts_with
以下查詢返回所有巢狀 favorites > catBreed 鍵值以 "Turkish" 開頭的使用者
- PostgreSQL
- MySQL
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: ['favorites', 'catBreed'],
string_starts_with: 'Turkish',
},
},
});
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: '$.favorites.catBreed',
string_starts_with: 'Turkish',
},
},
});
string_ends_with
以下查詢返回所有巢狀 favorites > catBreed 鍵值以 "Van" 結尾的使用者
- PostgreSQL
- MySQL
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: ['favorites', 'catBreed'],
string_ends_with: 'Van',
},
},
});
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: '$.favorites.catBreed',
string_ends_with: 'Van',
},
},
});
mode
指定字串篩選是否應區分大小寫(預設)或不區分大小寫。
以下查詢返回所有巢狀 favorites > catBreed 鍵值包含 "Van" 或 "van" 的使用者
- PostgreSQL
- MySQL
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: ['favorites', 'catBreed'],
string_contains: 'Van',
mode: "insensitive",
},
},
});
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: '$.favorites.catBreed',
string_contains: 'Van',
mode: "insensitive",
},
},
});
array_contains
以下查詢返回所有 sanctuaries 陣列包含值 "RSPCA" 的使用者
- PostgreSQL
- MySQL
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: ['sanctuaries'],
array_contains: ['RSPCA'],
},
},
});
注意:在 PostgreSQL 中,array_contains 的值必須是一個數組而不是字串,即使陣列只包含一個值。
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: '$.sanctuaries',
array_contains: 'RSPCA',
},
},
});
以下查詢返回所有 sanctuaries 陣列包含給定陣列中所有值的使用者
- PostgreSQL
- MySQL
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: ['sanctuaries'],
array_contains: ['RSPCA', 'Alley Cat Allies'],
},
},
});
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: '$.sanctuaries',
array_contains: ['RSPCA', 'Alley Cat Allies'],
},
},
});
array_starts_with
以下查詢返回所有 sanctuaries 陣列以值 "RSPCA" 開頭的使用者
- PostgreSQL
- MySQL
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: ['sanctuaries'],
array_starts_with: 'RSPCA',
},
},
});
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: '$.sanctuaries',
array_starts_with: 'RSPCA',
},
},
});
array_ends_with
以下查詢返回所有 sanctuaries 陣列以值 "Alley Cat Allies" 結尾的使用者
- PostgreSQL
- MySQL
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: ['sanctuaries'],
array_ends_with: 'Alley Cat Allies',
},
},
});
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: '$.sanctuaries',
array_ends_with: 'Alley Cat Allies',
},
},
});
客戶端方法
注意:客戶端級別的方法字首為 $。
備註
$on和$use客戶端方法在透過$extends擴充套件的客戶端例項上不存在
在擴充套件客戶端中,客戶端方法不一定存在。如果您正在擴充套件客戶端,請務必在使用 $transaction 或 $connect 等客戶端方法之前檢查其是否存在。
此外,如果您正在使用 $on 或 $use,您需要在擴充套件客戶端之前使用這些客戶端方法,因為這些方法在擴充套件客戶端上不存在。對於 $use,我們特別建議遷移到使用查詢擴充套件。
$disconnect()
$disconnect() 方法關閉呼叫 $connect 時建立的資料庫連線,並停止執行 Prisma ORM 查詢引擎的程序。有關 $connect() 和 $disconnect() 的概述,請參閱連線管理。
備註
$disconnect()返回一個Promise,因此您應該在帶有await關鍵字的async函式中呼叫它。
$connect()
$connect() 方法透過 Prisma ORM 的查詢引擎建立與資料庫的物理連線。有關 $connect() 和 $disconnect() 的概述,請參閱連線管理。
備註
$connect()返回一個Promise,因此您應該在帶有await關鍵字的async函式中呼叫它。
$on()
$on 在擴充套件客戶端中不可用。請遷移到客戶端擴充套件或在擴充套件客戶端之前使用 $on 方法。
$use()
$use() 方法新增中介軟體
prisma.$use(async (params, next) => {
console.log('This is middleware!');
// Modify or interrogate params here
return next(params);
});
next
next 表示中介軟體堆疊中的“下一層”,根據您在堆疊中的位置,它可能是下一個中介軟體或 Prisma 查詢。
params
params 是一個包含用於中介軟體資訊的物件。
| 引數 | 描述 |
|---|---|
action | 查詢型別——例如,create 或 findMany。 |
args | 傳遞給查詢的引數——例如,where、data 或 orderBy |
dataPath | 如果您使用流暢 API,則會填充此項。 |
model | 模型型別——例如,Post 或 User。 |
runInTransaction | 如果查詢在事務上下文中執行,則返回 true。 |
如果您需要 model 屬性作為字串,請使用:String(params.model)
示例引數值
{
args: { where: { id: 15 } },
dataPath: [ 'select', 'author', 'select', 'posts' ],
runInTransaction: false,
action: 'findMany',
model: 'Post'
}
示例
請參閱中介軟體示例。
$queryRawTyped
請參閱:使用原始 SQL ($queryRawTyped)。
$queryRaw
請參閱:使用原始 SQL ($queryRaw)。
$queryRawUnsafe()
請參閱:使用原始 SQL ($queryRawUnsafe())。
$executeRaw
$executeRawUnsafe()
請參閱:使用原始 SQL ($executeRawUnsafe())。
$runCommandRaw()
請參閱:使用原始 SQL ($runCommandRaw())。
$transaction()
請參閱:事務。
$metrics
Prisma Client 指標為您提供了 Prisma Client 如何與資料庫互動的詳細見解。您可以使用此見解來幫助診斷應用程式的效能問題。瞭解更多:指標。
Prisma Client 指標具有以下方法
$metrics.json():以 JSON 格式檢索 Prisma Client 指標。$metrics.prometheus():以 Prometheus 格式檢索 Prisma Client 指標。
$extends
使用 $extends,您可以建立和使用 Prisma Client 擴充套件,以以下方式向 Prisma Client 新增功能
model:向您的模型新增自定義方法client:向您的客戶端新增自定義方法query:建立自定義 Prisma Client 查詢result:向您的查詢結果新增自定義欄位
瞭解更多:Prisma Client 擴充套件。
實用型別
實用型別是 Prisma 名稱空間中的輔助函式和型別。它們對於保持應用程式型別安全很有用。
Prisma.validator
validator 幫助您基於架構模型建立可重用的查詢引數,同時確保您建立的物件是有效的。另請參閱:使用 Prisma.validator
您可以透過兩種方式使用 validator
使用生成的 Prisma Client 型別
使用型別提供了一種型別級別的方法來驗證資料
Prisma.validator<GeneratedType>({ args });
使用“選擇器”
使用選擇器模式時,您可以使用現有 Prisma Client 例項來建立驗證器。此模式允許您選擇要驗證的模型、操作和查詢選項。
您還可以使用已透過Prisma Client 擴充套件進行擴充套件的 Prisma Client 例項。
Prisma.validator(PrismaClientInstance, '<model>', '<operation>', '<query option>')({ args });
示例
以下示例展示瞭如何在應用中提取和驗證可重用的 create 操作的輸入
import { Prisma } from '@prisma/client';
const validateUserAndPostInput = (name, email, postTitle) => {
return Prisma.validator<Prisma.UserCreateInput>()({
name,
email,
posts: {
create: {
title: postTitle,
},
},
});
};
這是同一操作的另一種語法
import { Prisma } from '@prisma/client';
import prisma from './prisma';
const validateUserAndPostInput = (name, email, postTitle) => {
return Prisma.validator(
prisma,
'user',
'create',
'data'
)({
name,
email,
posts: {
create: {
title: postTitle,
},
},
});
};
比較同一表中的列
您可以直接比較同一表中的列,適用於非唯一過濾器。
此功能在 5.0.0 版本中已普遍可用,並從 Prisma ORM 4.3.0 到 4.16.2 版本透過 fieldReference 預覽功能提供。
在以下情況下,您必須使用原始查詢來比較同一表中的列
- 如果您的版本早於 4.3.0
- 如果您想使用唯一過濾器,例如
findUnique或findUniqueOrThrow - 如果您想將欄位與唯一約束進行比較
- 如果您想使用以下運算子之一,在 MySQL 或 MariaDB 中將JSON 欄位與另一個欄位進行比較:
gt、gte、lt或lte。請注意,您可以使用這些運算子將 JSON 欄位與標量值進行比較。此限制僅適用於您嘗試將 JSON 欄位與另一個欄位進行比較的情況。
要比較同一表中的列,請使用 <model>.fields 屬性。在以下示例中,查詢返回 prisma.product.quantity 欄位中的值小於或等於 prisma.product.warnQuantity 欄位中的值的所有記錄。
prisma.product.findMany({
where: { quantity: { lte: prisma.product.fields.warnQuantity } },
});
fields 是每個模型的特殊屬性。它包含該模型的欄位列表。
注意事項
欄位必須是同一型別
您只能對同一型別的欄位進行比較。例如,以下情況會引發錯誤
await prisma.order.findMany({
where: {
id: { equals: prisma.order.fields.due },
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Type error: id is a string, while amountDue is an integer
},
});
欄位必須在同一模型中
您只能使用 fields 屬性對同一模型中的欄位進行比較。以下示例不起作用
await prisma.order.findMany({
where: {
id: { equals: prisma.user.fields.name },
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Type error: name is a field on the User model, not Order
},
});
但是,您可以使用標準查詢比較不同模型中的欄位。
在 groupBy 模型查詢中,將引用的欄位放入 by 引數中
如果您使用帶有 having 選項的 groupBy 模型查詢,則必須將引用的欄位放入 by 引數中。
以下示例有效
prisma.user.groupBy({
by: ['id', 'name'],
having: { id: { equals: prisma.user.fields.name } },
});
以下示例無效,因為 name 不在 by 引數中
prisma.user.groupBy({
by: ['id'],
having: { id: { equals: prisma.user.fields.name } },
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// name is not in the 'by' argument
});
在標量列表中搜索欄位
如果您的資料來源支援標量列表(例如在 PostgreSQL 中),則可以搜尋特定欄位位於欄位列表中的所有記錄。為此,請使用 in 和 notIn 過濾器引用標量列表。例如
await prisma.user.findMany({
where: {
// find all users where 'name' is in a list of tags
name: { in: prisma.user.fields.tags },
},
});
使用 UserWhereUniqueInput 篩選非唯一欄位
從 5.0.0 版本開始,where 上生成的型別 UserWhereUniqueInput 會公開模型上的所有欄位,而不僅僅是唯一欄位。此功能在 4.5.0 到 4.16.2 版本之間,透過 extendedWhereUnique 預覽標誌提供
您必須在 where 語句中在布林運算子之外指定至少一個唯一欄位,並且可以指定任意數量的附加唯一和非唯一欄位。您可以使用此功能向返回單個記錄的任何操作新增過濾器。例如,您可以將此功能用於以下情況
從 4.6.0 版本開始,您可以使用此功能篩選可選的一對一巢狀讀取。
更新的樂觀併發控制
您可以篩選非唯一欄位以在 update 操作上執行樂觀併發控制。
要執行樂觀併發控制,我們建議您使用 version 欄位來檢查記錄或相關記錄中的資料在程式碼執行期間是否已更改。在 4.5.0 版本之前,您無法在 update 操作中評估 version 欄位,因為該欄位是非唯一的。從 4.5.0 版本開始,您可以評估 version 欄位。
在以下示例中,updateOne 和 updateTwo 首先讀取同一條記錄,然後嘗試更新它。資料庫僅在 version 中的值與初始讀取時的值相同時才執行這些更新。當資料庫執行這些更新中的第一個(可能是 updateOne 或 updateTwo,取決於時序)時,它會遞增 version 中的值。這意味著資料庫不會執行第二個更新,因為 version 中的值已更改。
model User {
id Int @id @default(autoincrement())
email String @unique
city String
version Int
}
function updateOne() {
const user = await prisma.user.findUnique({ id: 1 });
await prisma.user.update({
where: { id: user.id, version: user.version },
data: { city: 'Berlin', version: { increment: 1 } },
});
}
function updateTwo() {
const user = await prisma.user.findUnique({ id: 1 });
await prisma.user.update({
where: { id: user.id, version: user.version },
data: { city: 'New York', version: { increment: 1 } },
});
}
function main() {
await Promise.allSettled([updateOne(), updateTwo()]);
}
許可權檢查
您可以在更新期間篩選非唯一欄位以檢查許可權。
在以下示例中,使用者想要更新帖子標題。where 語句檢查 authorId 中的值以確認使用者是該帖子的作者。只有當用戶是帖子作者時,應用程式才會更新帖子標題。
await prisma.post.update({
where: { id: 1, authorId: 1 },
data: { title: 'Updated post title' },
});
軟刪除
您可以篩選非唯一欄位以處理軟刪除。
在以下示例中,如果帖子被軟刪除,我們不希望返回該帖子。該操作僅在 isDeleted 中的值為 false 時才返回帖子。
prisma.Post.findUnique({ where: { id: postId, isDeleted: false } });
UserWhereUniqueInput 注意事項
與 UserWhereUniqueInput 配合使用的布林運算子
對於 UserWhereUniqueInput,您必須在布林運算子 AND、OR、NOT 之外指定至少一個唯一欄位。您仍然可以將這些布林運算子與過濾器中的任何其他唯一欄位或非唯一欄位結合使用。
在以下示例中,我們將 id(一個唯一欄位)與 email 結合測試。這是有效的。
await prisma.user.update({
where: { id: 1, OR: [{ email: "bob@prisma.io" }, { email: "alice@prisma.io" }] },
// ^^^ Valid: the expression specifies a unique field (`id`) outside of any boolean operators
data: { ... }
})
// SQL equivalent:
// WHERE id = 1 AND (email = "bob@prisma.io" OR email = "alice@prisma.io")
以下示例無效,因為沒有任何布林運算子之外的唯一欄位
await prisma.user.update({
where: { OR: [{ email: "bob@prisma.io" }, { email: "alice@prisma.io" }] },
// ^^^ Invalid: the expressions does not contain a unique field outside of boolean operators
data: { ... }
})
一對一關係
從 4.5.0 版本開始,您可以在一對一關係的以下操作中篩選非唯一欄位
- 巢狀更新
- 巢狀插入或更新 (upsert)
- 巢狀斷開連線
- 巢狀刪除
Prisma Client 會自動使用唯一過濾器來選擇適當的相關記錄。因此,您不需要在 where 語句中透過 WhereUniqueInput 生成的型別指定唯一過濾器。相反,where 語句具有 WhereInput 生成的型別。您可以使用此型別進行過濾,而不受 WhereUniqueInput 的限制。
巢狀更新示例
await prisma.user.update({
where: { id: 1, },
data: {
to_one: {
// Before Prisma version 4.5.0
update: { field: "updated" }
// From Prisma version 4.5.0, you can also do the following:
update: { where: { /*WhereInput*/ }, data: { field: "updated" } } }
}
}
})
巢狀插入或更新 (upsert) 示例
await prisma.user.update({
where: { id: 1, },
data: {
to_one: {
upsert: {
where: { /* WhereInput */ } // new argument from Prisma 4.5.0
create: { /* CreateInput */ },
update: { /* CreateInput */ },
}
}
}
})
巢狀斷開連線示例
await prisma.user.update({
where: { id: 1, },
data: {
to_one: {
// Before Prisma version 4.5.0
disconnect: true
// From Prisma version 4.5.0, you can also do the following:
disconnect: { /* WhereInput */ }
}
}
})
巢狀刪除示例
await prisma.user.update({
where: { id: 1, },
data: {
to_one: {
// Before Prisma version 4.5.0
delete: true
// From Prisma version 4.5.0, you can also do the following:
delete: { /* WhereInput */ }
}
}
})
PrismaPromise 行為
所有 Prisma Client 查詢都返回 PrismaPromise 的例項。這是一個“thenable”,這意味著 PrismaPromise 僅在您呼叫 await 或 .then() 或 .catch() 時才執行。此行為與常規 JavaScript Promise 不同,後者會立即開始執行。
例如
const findPostOperation = prisma.post.findMany({}); // Query not yet executed
findPostOperation.then(); // Prisma Client now executes the query
// or
await findPostOperation; // Prisma Client now executes the query
使用 $transaction API 時,此行為使 Prisma Client 能夠將所有查詢作為一個事務傳遞給查詢引擎。