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。資料來源名稱包含在產生的 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" }] |
日誌層級
名稱 | 範例 |
---|---|
query | 記錄 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”, ], }, }) |
info | 範例prisma:info Started http server on http://127.0.0.1:58471 |
warn | 警告。 |
error | 錯誤。 |
Emit 格式
名稱 | 描述 |
---|---|
stdout | 請參閱:stdout |
event | 引發您可以訂閱的事件。 |
事件類型
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
欄位將會是 undefined。
所有其他日誌層級事件類型
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 傳回的錯誤層級和格式。
錯誤格式
名稱 | 描述 |
---|---|
undefined | 如果未定義,預設為 colorless。 |
pretty | 啟用美觀的錯誤格式。 |
colorless (預設) | 啟用無色彩的錯誤格式。 |
minimal | 啟用極簡的錯誤格式。 |
範例
無錯誤格式
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 { Pool, neonConfig } from '@neondatabase/serverless';
import { PrismaNeon } from '@prisma/adapter-neon';
import { PrismaClient } from '@prisma/client';
import dotenv from 'dotenv';
import ws from 'ws';
dotenv.config();
neonConfig.webSocketConstructor = ws;
const connectionString = `${process.env.DATABASE_URL}`;
const pool = new Pool({ connectionString });
const adapter = new PrismaNeon(pool);
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
選項
選項 | 描述 |
---|---|
RejectOnNotFound | 全域啟用 (true / false ) 或 拋出自訂錯誤。 |
RejectPerOperation | 依操作啟用 (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 中引入。
允許在建構子層級全域設定交易選項。
備註
- 交易層級可以在每個交易層級覆寫。
選項
選項 | 描述 |
---|---|
maxWait | Prisma Client 將等待從資料庫取得交易的最長時間。預設值為 2 秒。 |
timeout | 互動式交易在取消和回滾之前可以運行的最長時間。預設值為 5 秒。 |
isolationLevel | 設定交易隔離層級。預設情況下,這會設定為目前在您的資料庫中配置的值。可用的選項可能因您使用的資料庫而異。 |
範例
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 的 dataloader 自動批次處理具有相同
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 以來在 預覽 中 |
relationLoadStrategy | 'join' 或 'query' | 否 | 預設值:join 。指定關聯查詢的載入策略。僅在與 include (或關聯欄位上的 select ) 結合使用時可用。自 5.9.0 以來在 預覽 中。 |
傳回類型
傳回類型 | 範例 | 描述 |
---|---|---|
JavaScript 物件 (已輸入類型) | User | |
JavaScript 物件 (純物件) | { title: "Hello world" } | 使用 select 和 include 來決定要傳回哪些欄位。 |
null | null | 找不到記錄 |
範例
取得 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()
的不同之處如下
-
其傳回類型不可為 null。例如,
post.findUnique()
可以傳回post
或null
,但post.findUniqueOrThrow()
始終傳回post
。 -
它與
$transaction
API 中的循序操作不相容。如果查詢拋出PrismaClientKnownRequestError
,則 API 將不會回滾呼叫陣列中的任何操作。作為一種解決方案,您可以使用具有$transaction
API 的互動式交易,如下所示$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 以來在 預覽 中。 |
relationLoadStrategy | 'join' 或 'query' | 否 | 預設值:join 。指定關聯查詢的載入策略。僅在與 include (或關聯欄位上的 select ) 結合使用時可用。自 5.9.0 以來在 預覽 中。 |
where | UserWhereInput | 否 | 將所有模型欄位包裝在類型中,以便可以依任何屬性篩選列表。 |
orderBy | XOR<Enumerable<UserOrderByInput>, UserOrderByInput> | 否 | 讓您可以依任何屬性排序傳回的列表。 |
傳回類型
傳回類型 | 範例 | 描述 |
---|---|---|
JavaScript 物件 (已輸入類型) | User | 指定要在傳回物件上包含哪些屬性。 |
JavaScript 物件 (純物件) | { title: "Hello world" } | 使用 select 和 include 來決定要傳回哪些欄位。 |
null | null | 找不到記錄 |
備註
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()
的不同之處如下
-
其傳回類型不可為 null。例如,
post.findFirst()
可以傳回post
或null
,但post.findFirstOrThrow
始終傳回post
。 -
它與
$transaction
API 中的循序操作不相容。如果查詢傳回PrismaClientKnownRequestError
,則 API 將不會回滾呼叫陣列中的任何操作。作為一種解決方案,您可以使用具有$transaction
API 的互動式交易,如下所示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 以來在 預覽 中 |
relationLoadStrategy | 'join' 或 'query' | 否 | 預設值:join 。指定關聯查詢的載入策略。僅在與 include (或關聯欄位上的 select ) 結合使用時可用。自 5.9.0 以來在 預覽 中。 |
where | UserWhereInput | 否 | 將所有模型欄位包裝在類型中,以便可以依任何屬性篩選列表。 |
orderBy | XOR<Enumerable<PostOrder ByInput>, PostOrderByInput> | 否 | 讓您可以依任何屬性排序傳回的列表。 |
cursor | UserWhereUniqueInput | 否 | 指定列表的位置 (該值通常指定 id 或另一個唯一值)。 |
take | number | 否 | 指定應在列表中傳回多少個物件 (從列表的開頭 (正值) 或結尾 (負值) 或 從 cursor 位置 (如果已提及) 查看) |
skip | number | 否 | 指定應跳過列表中傳回的物件數量。 |
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 以來在 預覽 中 |
relationLoadStrategy | '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<UserUpdateInput UserUncheckedUpdateInput> | 是 | 包裝模型的所有欄位,以便在更新現有記錄時可以提供這些欄位。在資料模型中標記為選用或具有預設值的欄位是選用的。 |
where | UserWhereUniqueInput | 是 | 包裝模型的所有欄位,以便可以選取記錄 (深入了解)。 在 4.5.0 版本之前,此類型僅包裝模型的唯一欄位。 |
select | XOR<UserSelect, null> | 否 | 指定要在傳回物件上包含哪些屬性。 |
include | XOR<UserInclude, null> | 否 | 指定應在傳回物件上預先載入哪些關聯。 |
omit | XOR<UserOmit, null> | 否 | 指定要在傳回物件上排除哪些屬性。自 5.13.0 以來在 預覽 中。 |
relationLoadStrategy | '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
條件,它會建立新的資料庫記錄
選項
名稱 | 類型 | 必要 | 描述 |
---|---|---|---|
create | XOR<UserCreateInput, UserUncheckedCreateInput> | 是 | 包裝模型的所有欄位,以便在建立新記錄時可以提供這些欄位。它還包括關聯欄位,讓您可以執行 (交易式) 巢狀插入。在資料模型中標記為選用或具有預設值的欄位是選用的。 |
update | XOR<UserUpdateInput, UserUncheckedUpdateInput> | 是 | 包裝模型的所有欄位,以便在更新現有記錄時可以提供這些欄位。在資料模型中標記為選用或具有預設值的欄位是選用的。 |
where | UserWhereUniqueInput | 是 | 包裝模型的所有欄位,以便可以選取記錄 (深入了解)。 在 4.5.0 版本之前,此類型僅包裝模型的唯一欄位。 |
select | XOR<UserSelect, null> | 否 | 指定要在傳回物件上包含哪些屬性。 |
include | XOR<UserInclude, null> | 否 | 指定應在傳回物件上預先載入哪些關聯。 |
omit | XOR<UserOmit, null> | 否 | 指定要在傳回物件上排除哪些屬性。自 5.13.0 以來在 預覽 中 |
relationLoadStrategy | 'join' 或 'query' | 否 | 預設值:join 。指定關聯查詢的載入策略。僅在與 include (或關聯欄位上的 select ) 結合使用時可用。自 5.9.0 以來在 預覽 中。 |
傳回類型
傳回類型 | 範例 | 描述 |
---|---|---|
JavaScript 物件 (已輸入類型) | User | |
JavaScript 物件 (純物件) | { name: "Alice Wonderland" } | 使用 select 和 include 來決定要傳回哪些欄位。 |
備註
- 若要在更新時執行算術運算 (加法、減法、乘法、除法),請使用原子更新,以防止競爭條件。
- 如果同時發生兩個或多個 upsert 操作,且記錄尚不存在,則可能會發生競爭條件。因此,一個或多個 upsert 操作可能會拋出唯一索引鍵約束錯誤。您的應用程式程式碼可以捕獲此錯誤並重試操作。深入了解。
- 從 4.6.0 版本開始,Prisma ORM 會在可能的情況下將 upsert 查詢移交給資料庫。深入了解。
範例
更新(如果存在)或建立新的 User
記錄,email
為 alice@prisma.io
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 範例
以下範例使用此結構描述:
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 以來在 預覽 中 |
relationLoadStrategy | '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
和兩個具有巢狀createMany
的Post
記錄。
範例
建立多個新使用者
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()
查詢內使用巢狀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 | 否 | 包裝模型的所有欄位,以便可以按任何屬性篩選清單。如果您不篩選清單,則所有記錄都將被更新。 |
limit | number | 否 | 限制要更新的記錄數量。 |
回傳類型
傳回類型 | 範例 | 描述 |
---|---|---|
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 | 否 | 包裝模型的所有欄位,以便可以按任何欄位篩選清單。 |
limit | Int | 否 | 限制已刪除的記錄數量。 |
回傳類型
傳回類型 | 範例 | 描述 |
---|---|---|
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<PostOrder ByInput>, PostOrderByInput> | 否 | 讓您可以依任何屬性排序傳回的列表。 |
cursor | UserWhereUniqueInput | 否 | 指定列表的位置 (該值通常指定 id 或另一個唯一值)。 |
take | number | 否 | 指定應在列表中傳回多少個物件 (從列表的開頭 (正值) 或結尾 (負值) 或 從 cursor 位置 (如果已提及) 查看) |
skip | number | 否 | 指定應跳過列表中傳回的物件數量。 |
回傳類型
傳回類型 | 範例 | 描述 |
---|---|---|
number | 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
) - 具有非
null
name
欄位的所有記錄的計數 - 具有非
null
city
欄位的所有記錄的計數
const c = await prisma.user.count({
select: {
_all: true,
city: true,
name: true,
},
});
aggregate()
另請參閱:彙總、分組和摘要
選項
名稱 | 類型 | 必要 | 描述 |
---|---|---|---|
where | UserWhereInput | 否 | 將所有模型欄位包裝在類型中,以便可以依任何屬性篩選列表。 |
orderBy | XOR<Enumerable<UserOrderByInput>, UserOrderByInput> | 否 | 讓您可以依任何屬性排序傳回的列表。 |
cursor | UserWhereUniqueInput | 否 | 指定列表的位置 (該值通常指定 id 或另一個唯一值)。 |
take | number | 否 | 指定應在列表中傳回多少個物件 (從列表的開頭 (正值) 或結尾 (負值) 或 從 cursor 位置 (如果已提及) 查看) |
skip | number | 否 | 指定應跳過列表中傳回的物件數量。 |
_count | true | 否 | 回傳符合記錄或非 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 | number | 否 | 指定應在列表中傳回多少個物件 (從列表的開頭 (正值) 或結尾 (負值) 或 從 cursor 位置 (如果已提及) 查看) |
skip | number | 否 | 指定應跳過列表中傳回的物件數量。 |
_count | true | UserCountAggregateInputType | 否 | 回傳符合記錄或非 null 欄位的計數。 |
_avg | UserAvgAggregateInputType | 否 | 回傳指定欄位所有值的平均值。 |
_sum | UserSumAggregateInputType | 否 | 回傳指定欄位所有值的總和。 |
_min | UserMinAggregateInputType | 否 | 回傳指定欄位的最小可用值。 |
_max | UserMaxAggregateInputType | 否 | 回傳指定欄位的最大可用值。 |
範例
依 country
/city
分組,其中 profileViews
的平均值大於 200
,並回傳每個群組的 profileViews
的 _sum
查詢還會回傳每個群組中 _all
記錄的計數,以及每個群組中具有非 null
city
欄位值的所有記錄。
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()
請參閱:使用原始 SQL (findRaw()
)。
aggregateRaw()
請參閱:使用原始 SQL (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,
},
},
},
});
include
內部 select
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 ORM 版本5.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 結構描述檔案中透過 relationJoins
預覽功能標誌啟用它:
generator client {
provider = "prisma-client-js"
previewFeatures = ["relationJoins"]
}
新增此標誌後,您需要再次執行 prisma generate
以重新產生 Prisma Client。此功能目前適用於 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',
}) -
PostScalarWhereInput
const 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
- 此類型將更新 ID 符合的Post
記錄的 title 欄位;如果該記錄不存在,則會改為建立它。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
- 此類型將更新所有 published 設定為 false 的Post
記錄。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
一起使用
UserOrderByInput
const 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' },
];
請注意,現在除了 "Paris, France" 之外,還有 "Paris, Denmark"
結合篩選器選取 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'],
});
巢狀查詢
create
巢狀 create
查詢會將新的關聯記錄或記錄集新增至父記錄。請參閱:處理關聯
備註
- 當您
create()
(prisma.user.create(...)
) 新的父記錄或update()
(prisma.user.update(...)
) 現有的父記錄時,create
可作為巢狀查詢使用。 - 您可以使用巢狀
create
或 巢狀createMany
來建立多個關聯記錄。如果您需要skipDuplicates
查詢選項,則應使用createMany
。
範例
建立新的 User
記錄以及新的 Profile
記錄
const user = await prisma.user.create({
data: {
email: 'alice@prisma.io',
profile: {
create: { bio: 'Hello World' },
},
},
});
建立新的 Profile
記錄以及新的 User
記錄
const user = await prisma.profile.create({
data: {
bio: 'Hello World',
user: {
create: { email: 'alice@prisma.io' },
},
},
})
建立新的 User
記錄以及新的 Post
記錄
const user = await prisma.user.create({
data: {
email: 'alice@prisma.io',
posts: {
create: { title: 'Hello World' },
},
},
});
建立新的 User
記錄以及兩個新的 Post
記錄
由於它是一對多關聯,您也可以透過將陣列傳遞至 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' },
},
},
});
透過將現有的 User
記錄連接到現有的 Profile
記錄來更新它
const user = await prisma.user.update({
where: { email: 'alice@prisma.io' },
data: {
profile: {
connect: { id: 24 },
},
},
});
透過將現有的 User
記錄連接到兩個現有的 Post
記錄來更新它
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' },
},
},
},
});
透過將現有的 User
記錄連接到現有的 Profile
記錄,或建立新的 Profile
記錄來更新它
以下範例
- 嘗試將使用者連接到
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',
},
},
},
},
});
透過將現有的 User
記錄連接到兩個現有的 Post
記錄,或建立兩個新的 Post
記錄來更新它
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
查詢會在關聯記錄存在時更新它,或建立新的關聯記錄。
範例
透過更新其連接的 Profile
記錄或建立新的記錄 (upsert) 來更新現有的 User
記錄
const user = await prisma.user.update({
where: { email: 'alice@prisma.io' },
data: {
profile: {
upsert: {
create: { bio: 'Hello World' },
update: { bio: 'Hello World' },
},
},
},
});
透過更新其連接的兩個 Post
記錄或建立新的記錄 (upsert) 來更新現有的 User
記錄
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
才可用。
範例
透過刪除其連接的 Profile
記錄來更新現有的 User
記錄
const user = await prisma.user.update({
where: { email: 'alice@prisma.io' },
data: {
profile: {
delete: true,
},
},
});
更新現有的 User
記錄,方法是刪除與其關聯的兩個 Post
記錄
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: {},
},
},
});
篩選條件和運算子
- 從 4.3.0 版本開始,您也可以使用這些運算子來比較同一模型中的欄位 搭配
<model>.fields
屬性。 - 在 4.3.0 之前的版本中,您可以使用原始查詢來比較同一模型中的欄位。
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
}
},
});
not
值不等於 n
。
範例
傳回所有 name
不等於 "Eleanor"
的使用者
const result = await prisma.user.findMany({
where: {
name: {
not: 'Eleanor',
},
},
});
not
將傳回所有不符合給定值的項目。但是,如果欄位可為 null,則不會傳回 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'] },
},
},
});
取得 User
記錄,其中至少一篇 Post
具有至少一個指定的 Category
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
開頭的 Post
記錄 (例如 Prisma
)
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
來傳回至少有一個關聯的所有記錄
範例
取得某些文章提及 Prisma
的所有 User
記錄
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。
- 您可以推送值列表或僅推送單一值。
範例
將 computing
項目新增到 tags
列表
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
此方法僅在 3.11.1 及更高版本的 MongoDB 上可用。
使用 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
此篩選器僅在 3.11.1 及更高版本的 MongoDB 上可用。
篩選列表以僅包含已設定的結果 (已設定為值,或明確設定為 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
複合類型的 zip 欄位
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
篩選複合類型清單,其中清單中的每個項目都符合條件
範例
尋找第一個每張照片的 height
都是 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',
},
},
});
用戶端方法
注意: 用戶端層級方法以 $
為前綴。
備註
- 使用
$extends
擴充的擴充用戶端實例上不存在$on
和$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
引數中
如果您將 groupBy 模型查詢與 having
選項搭配使用,則必須將您參照的欄位放在 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
之外至少指定一個唯一欄位。您仍然可以將這些布林運算子與篩選器中的任何其他唯一欄位或非唯一欄位結合使用。
在以下範例中,我們搭配 email
測試唯一欄位 id
。這是有效的。
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 版開始,您可以在一對一關聯的下列運算中篩選非唯一欄位
- 巢狀更新
- 巢狀更新插入
- 巢狀中斷連線
- 巢狀刪除
Prisma Client 會自動使用唯一篩選器來選取適當的相關記錄。因此,您不需要在使用 產生的類型 WhereUniqueInput
的 where
陳述式中指定唯一篩選器。相反地,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" } } }
}
}
})
巢狀更新插入範例
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 可以將所有查詢作為單一交易傳遞至查詢引擎。