Prisma Client APIリファレンス
Prisma Client APIリファレンスドキュメントは、以下のスキーマに基づいています
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を再生成する必要があります。データソース名は生成されたクライアントに含まれます。
- スキーマで
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 シェル形式でクエリをログに記録します。例prisma:query db.User.deleteMany({ _id: ( $in: [ “6221ce49f756b0721fc00542”, ], }, }) |
info | 例prisma:info http://127.0.0.1:58471 でHTTPサーバーを起動しました |
warn | 警告。 |
error | エラー。 |
出力形式
名前 | 説明 |
---|---|
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
フィールドは未定義になることに注意してください。
その他のすべてのログレベルイベントタイプ
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 | 定義されていない場合、デフォルトはカラーレスです。 |
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 { 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
を設定できます。
オプション
オプション | 説明 |
---|---|
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のデータローダーは、同じ
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 | 数値 | いいえ | リストに返されるオブジェクトの数を指定します(リストの先頭(正の値)または末尾(負の値)、またはcursor 位置が指定されている場合はそこから)。 |
skip | 数値 | いいえ | リスト内で返されるオブジェクトのうち、スキップする数を指定します。 |
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
と2つのPost
レコードを同時に追加します。
例
必須フィールドemail
のみで単一の新しいレコードを作成する
const user = await prisma.user.create({
data: { email: 'alice@prisma.io' },
});
複数の新しいレコードを作成する
ほとんどの場合、createMany()
またはcreateManyAndReturn()
クエリを使用してバッチ挿入を実行できます。しかし、create()
が複数のレコードを挿入する最適なオプションとなるシナリオもあります。
以下の例では、2つの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 例外 | レコードが存在しない場合、例外がスローされます。 |
備考
- 更新時に算術演算(加算、減算、乗算、除算)を実行するには、競合状態を防ぐためにアトミック更新を使用します。
- ネストされた
update
を実行することもできます。たとえば、ユーザーとそのユーザーの投稿を同時に更新します。
例
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 を使用します。 |
備考
- 更新時に算術演算(加算、減算、乗算、除算)を実行するには、競合状態を防ぐためにアトミック更新を使用します。
- 2つ以上のupsert操作が同時に発生し、レコードがまだ存在しない場合、競合状態が発生する可能性があります。結果として、1つ以上のupsert操作が一意キー制約エラーをスローする可能性があります。アプリケーションコードはこのエラーをキャッチし、操作を再試行できます。詳細はこちら。
- バージョン4.6.0以降、Prisma ORMは可能な限りupsertクエリをデータベースに引き渡します。詳細はこちら。
例
email
が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操作が同時に発生し、レコードがまだ存在しない場合、1つ以上の操作がユニークキー制約エラーを返す可能性があります。
原因
Prisma Clientがupsertを実行する際、まずデータベースにそのレコードが既に存在するかどうかを確認します。このチェックを行うために、Prisma Clientはupsert操作のwhere
句を使用して読み取り操作を実行します。これには、以下の2つの可能な結果があります。
- レコードが存在しない場合、Prisma Clientはそのレコードを作成します。
- レコードが存在する場合、Prisma Clientはそれを更新します。
アプリケーションが2つ以上の同時upsert操作を実行しようとすると、競合状態が発生し、2つ以上の操作がレコードを見つけられず、そのレコードを作成しようとする可能性があります。この状況では、いずれかの操作が新しいレコードの作成に成功しますが、他の操作は失敗し、ユニークキー制約エラーを返します。
解決策
アプリケーションコードで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クエリの基準
Prisma Clientは、クエリが以下の基準を満たす場合に、upsert
クエリにデータベースupsertを使用します。
upsert
のcreate
およびupdate
オプションにネストされたクエリがないこと- クエリにネストされた読み取りを使用する選択が含まれていないこと
- クエリが1つのモデルのみを変更すること
upsert
のwhere
オプションに一意なフィールドが1つだけであること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以降、
createMany()
はSQLiteでサポートされるようになりました。 skipDuplicates
オプションはMongoDB、SQLServer、SQLiteではサポートされていません。- トップレベルの
createMany()
クエリ内でネストされたcreate
、createMany
、connect
、connectOrCreate
クエリを使用してリレーションを作成または接続することはできません。回避策については、こちらを参照してください。 update()
またはcreate()
クエリ内でネストされたcreateMany
クエリを使用できます。たとえば、ネストされたcreateMany
を使用して、User
と2つの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は含まれません |
備考
skipDuplicates
オプションはSQLiteではサポートされていません。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 | いいえ | リストを任意のプロパティでフィルタリングできるように、モデルのすべてのフィールドをラップします。リストをフィルタリングしない場合、すべてのレコードが更新されます。 |
limit | 数値 | いいえ | 更新するレコードの数を制限します。 |
戻り値の型
戻り値の型 | 例 | 説明 |
---|---|---|
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
が含まれ、かつ少なくとも1つの関連する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 | 整数 | いいえ | 削除されるレコードの数を制限します。 |
戻り値の型
戻り値の型 | 例 | 説明 |
---|---|---|
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 | 数値 | いいえ | リストに返されるオブジェクトの数を指定します(リストの先頭(正の値)または末尾(負の値)、またはcursor 位置が指定されている場合はそこから)。 |
skip | 数値 | いいえ | リスト内で返されるオブジェクトのうち、スキップする数を指定します。 |
戻り値の型
戻り値の型 | 例 | 説明 |
---|---|---|
数値 | 29 | レコードの数。 |
UserCountAggregateOutputType | { _all: 27, name: 10 } | select が使用されている場合に返されます。 |
例
すべてのUser
レコードの数を数える
const result = await prisma.user.count();
少なくとも1つの公開されたPost
を持つすべてのUser
レコードを数える
const result = await prisma.user.count({
where: {
post: {
some: {
published: true,
},
},
},
});
select
を使用して3つの個別のカウントを実行する
以下のクエリは以下を返します
- すべてのレコードの数(
_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> | いいえ | 返されるリストを任意のプロパティで並べ替えることができます。 |
cursor | UserWhereUniqueInput | いいえ | リストの位置を指定します(値は通常、id または他の一意な値を指定します)。 |
take | 数値 | いいえ | リストに返されるオブジェクトの数を指定します(リストの先頭(正の値)または末尾(負の値)、またはcursor 位置が指定されている場合はそこから)。 |
skip | 数値 | いいえ | リスト内で返されるオブジェクトのうち、スキップする数を指定します。 |
_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 | 数値 | いいえ | リストに返されるオブジェクトの数を指定します(リストの先頭(正の値)または末尾(負の値)、またはcursor 位置が指定されている場合はそこから)。 |
skip | 数値 | いいえ | リスト内で返されるオブジェクトのうち、スキップする数を指定します。 |
_count | true | UserCountAggregateInputType | いいえ | 一致するレコードまたはnullではないフィールドの数を返します。 |
_avg | UserAvgAggregateInputType | いいえ | 指定されたフィールドのすべての値の平均を返します。 |
_sum | UserSumAggregateInputType | いいえ | 指定されたフィールドのすべての値の合計を返します。 |
_min | UserMinAggregateInputType | いいえ | 指定されたフィールドの利用可能な最小値を返します。 |
_max | UserMaxAggregateInputType | いいえ | 指定されたフィールドの利用可能な最大値を返します。 |
例
平均profileViews
が200
より大きいcountry
/city
でグループ化し、各グループの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()
参照:Raw 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,
},
},
},
});
select
内のinclude
const result = await prisma.user.findMany({
select: {
id: true,
name: true,
posts: {
include: {
author: true,
},
},
},
});
select
のために生成された型
以下の例は、select
でvalidator
を使用する方法を示しています
const selectNameEmailNotPosts = Prisma.validator<Prisma.UserSelect>()({
name: true,
email: true,
posts: false,
});
include
include
は、Prisma Clientが返す結果にどの関連を含めるかを定義します。参照:フィールドの選択と関連のインクルード。
備考
- 3.0.1以降、関連の
_count
をinclude
できます。
例
User
レコードをロードする際にposts
およびprofile
関連を含める
const users = await prisma.user.findMany({
include: {
posts: true, // Returns all fields for all posts
profile: true, // Returns all Profile fields
},
});
2つの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
のために生成された型
以下の例は、include
でvalidator
を使用する方法を示しています
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
のために生成された型
以下の例は、omit
でvalidator
を使用する方法を示しています
const omitPassword = Prisma.validator<Prisma.UserOmit>()({
password: true,
});
relationLoadStrategy
(プレビュー)
relationLoadStrategy
は、関連がデータベースからどのようにロードされるかを指定します。これには2つの可能な値があります。
join
(デフォルト):データベースレベルのLATERAL JOIN
(PostgreSQL)または相関サブクエリ(MySQL)を使用し、データベースへの単一のクエリですべてのデータをフェッチします。query
:データベースに複数のクエリを送信し(テーブルごとに1つ)、アプリケーションレベルでそれらを結合します。
注意:
relationLoadStrategy
がプレビューから一般提供に移行すると、すべての関連クエリでjoin
が普遍的にデフォルトとなります。
結合戦略の詳細については、こちらを参照してください。
relationLoadStrategy
オプションは現在プレビュー段階であるため、PrismaスキーマファイルでrelationJoins
プレビュー機能フラグを介して有効にする必要があります
generator client {
provider = "prisma-client-js"
previewFeatures = ["relationJoins"]
}
このフラグを追加した後、Prisma Clientを再生成するためにprisma generate
を再度実行する必要があります。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
は1つ以上のフィルターを定義し、レコードのプロパティ(ユーザーのメールアドレスなど)や関連レコードのプロパティ(ユーザーの最新の投稿トップ10のタイトルなど)でフィルターするために使用できます。
例
const results = await prisma.user.findMany({
where: {
email: {
endsWith: 'prisma.io',
},
},
});
where
のために生成された型
以下の例は、where
でvalidator
を使用する方法を示しています
-
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
)を受け取り、Author
を除くPost
モデル上の任意のフィールドを更新します。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
レコードのリストをソートします。参照:ソート
備考
-
2.16.0以降、関連フィールドで並べ替えることができます。たとえば、投稿を著者の名前で並べ替えることができます。
-
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 値を最後にしてソートします。 |
例
User
をemail
フィールドでソートする
以下の例は、すべてのUser
レコードをemail
の昇順でソートして返します
const users = await prisma.user.findMany({
orderBy: {
email: 'asc',
},
});
以下の例は、すべてのUser
レコードをemail
の降順でソートして返します
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',
},
},
});
複数のフィールド (email
とrole
) でUser
を並べ替え
次の例は、最初にemail
、次にrole
の2つのフィールドでユーザーを並べ替えます
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',
},
],
});
User
をemail
で並べ替え、name
とemail
を選択
次の例は、すべてのUser
レコードのname
とemail
フィールドを、email
で並べ替えて返します
const users3 = await prisma.user.findMany({
orderBy: {
email: 'asc',
},
select: {
name: true,
email: true,
},
});
User
レコードをemail
で並べ替え、ネストされたPost
レコードをtitle
で並べ替え
次の例
email
で並べ替えられたすべてのUser
レコードを返します- 各
User
レコードについて、ネストされたすべてのPost
レコードのtitle
フィールドを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
で並べ替え
次の例は、すべてのUser
レコードをrole
(enum
)で並べ替えます
const sort = await prisma.user.findMany({
orderBy: {
role: 'desc',
},
select: {
email: true,
role: true,
},
});
orderBy
のために生成された型
次の例は、orderBy
でvalidator
を使用する方法を示しています
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' },
];
"パリ、フランス"に加えて"パリ、デンマーク"があることに注意してください
フィルターと組み合わせてDistinctを選択
次の例は、ユーザーのメールが"prisma.io"
を含むすべての異なるcity
とcountry
のフィールドの組み合わせを返し、city
とcountry
フィールドのみを選択します
const distinctCitiesAndCountries = await prisma.user.findMany({
where: {
email: {
contains: 'prisma.io',
},
},
select: {
city: true,
country: true,
},
distinct: ['city', 'country'],
});
nativeDistinct
PrismaスキーマでnativeDistinct
を有効にすると、distinct
操作がデータベース層にプッシュされます(サポートされている場合)。これにより、パフォーマンスが大幅に向上する可能性があります。ただし、次の点に注意してください。
- 一部のデータベースでは、特定のフィールドの組み合わせでのDISTINCTが完全にサポートされていない場合があります。
- プロバイダーによって動作が異なる場合があります。
nativeDistinct
を有効にするには
generator client {
provider = "prisma-client-js"
previewFeatures = ["nativeDistinct"]
}
詳細については、プレビュー機能を参照してください。
ネストされたクエリ
create
ネストされたcreate
クエリは、新しい関連レコードまたはレコードのセットを親レコードに追加します。参照:リレーションの操作
補足
create
は、新しい親レコードをcreate()
(prisma.user.create(...)
)する場合、または既存の親レコードをupdate()
(prisma.user.update(...)
)する場合に、ネストされたクエリとして利用できます。- 複数の関連レコードを作成するには、ネストされた
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' },
},
},
});
2つの新しい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
クエリは、新しいレコードセットを親レコードに追加します。参照:リレーションの操作
補足
createMany
は、新しい親レコードをcreate()
(prisma.user.create(...)
)する場合、または既存の親レコードをupdate()
(prisma.user.update(...)
)する場合に、ネストされたクエリとして利用できます。- 多対一のリレーションのコンテキストで利用できます。たとえば、
prisma.user.create(...)
でユーザーを作成し、ネストされたcreateMany
を使用して複数の投稿を作成できます(投稿は一人のユーザーに属します)。 - 多対多のリレーションのコンテキストでは利用できません。たとえば、
prisma.post.create(...)
で投稿を作成し、ネストされたcreateMany
を使用してカテゴリを作成することはできません(多くの投稿が多くのカテゴリを持つ場合)。
- 多対一のリレーションのコンテキストで利用できます。たとえば、
- 追加の
create
またはcreateMany
をネストすることはできません。 - 外部キーを直接設定できます。たとえば、投稿に
categoryId
を設定するなど。 - Prisma ORMバージョン5.12.0以降、ネストされた
createMany
はSQLiteでサポートされています。 - 複数の関連レコードを作成するには、ネストされた
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
レコードのリストを別のリストで置き換えます。参照:リレーションの操作
例
既存のUser
レコードを更新し、以前のPost
レコードをすべて切断して、他の既存の2つのレコードを接続
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
を一緒に使用する場合、適用される順序が結果に大きく影響します。set
がconnect
の前に使用されると、接続されたレコードはconnect
操作によって確立された最終状態のみを反映します。なぜなら、set
はconnect
が新しい接続を確立する前に既存のすべての接続をクリアするからです。逆に、connect
がset
の前に適用されると、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 },
},
},
});
既存のUser
レコードを2つの既存のPost
レコードに接続して更新
const user = await prisma.user.update({
where: { email: 'alice@prisma.io' },
data: {
posts: {
connect: [{ id: 24 }, { id: 42 }],
},
},
});
connectOrCreate
connectOrCreate
は、IDまたは一意の識別子によってレコードを既存の関連レコードに接続するか、レコードが存在しない場合は新しい関連レコードを作成します。参照:リレーションの操作
補足
-
同時トランザクションとして実行される複数の
connectOrCreate
クエリは、競合状態を引き起こす可能性があります。次の例を考えてみましょう。2つのクエリが同時にcomputing
というブログ投稿タグをconnectOrCreate
しようとします(タグ名は一意でなければなりません)。- クエリ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
を作成
次の例
- プロファイルを作成します
- メールアドレスが
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
にユーザーを接続しようとします - 一致するプロファイルが存在しない場合、新しいプロファイルを作成します
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
レコードを、既存の2つのPost
レコードに接続するか、新しい2つの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
は、リレーションがオプショナルである場合にのみ利用可能です。 -
切断しようとしているリレーションシップが存在しない場合
例
接続されているProfile
レコードを切断して、既存のUser
レコードを更新
const user = await prisma.user.update({
where: { email: 'bob@prisma.io' },
data: {
profile: {
disconnect: true,
},
},
});
接続されている2つのPost
レコードを切断して、既存のUser
レコードを更新
const user = await prisma.user.update({
where: { email: 'alice@prisma.io' },
data: {
posts: {
disconnect: [{ id: 44 }, { id: 46 }],
},
},
});
update
ネストされたupdate
クエリは、親レコードのIDがn
である1つ以上の関連レコードを更新します。参照:リレーションの操作
補足
-
ネストされた
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' },
},
},
});
接続されている2つの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
レコードを更新するか、新しいレコードを作成(upsert)して更新
const user = await prisma.user.update({
where: { email: 'alice@prisma.io' },
data: {
profile: {
upsert: {
create: { bio: 'Hello World' },
update: { bio: 'Hello World' },
},
},
},
});
既存のUser
レコードを、接続されている2つのPost
レコードを更新するか、新しいレコードを作成(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
は、リレーションがオプショナルである場合にのみ利用可能です。
例
接続されているProfile
レコードを削除して、既存のUser
レコードを更新
const user = await prisma.user.update({
where: { email: 'alice@prisma.io' },
data: {
profile: {
delete: true,
},
},
});
接続されている2つの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
値は返されません。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
が次のリスト[22, 91, 14, 2, 5]
に含まれるUser
レコードを取得
const getUser = await prisma.user.findMany({
where: {
id: { in: [22, 91, 14, 2, 5] },
},
});
name
が次のリスト['Saqui', 'Clementine', 'Bob']
に含まれるUser
レコードを取得
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'] },
},
},
});
少なくとも1つのPost
に少なくとも1つの指定された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
が次のリスト[22, 91, 14, 2, 5]
に見つからないUser
レコードを取得
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
1つ以上の条件が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
フィルタリング条件に一致する1つ以上(「一部」)の関連レコードを持つすべてのレコードを返します。
補足
- パラメータなしで
some
を使用すると、少なくとも1つのリレーションを持つすべてのレコードが返されます
例
いくつかの投稿がPrisma
に言及しているすべてのUser
レコードを取得
const result = await prisma.user.findMany({
where: {
post: {
some: {
content: {
contains: "Prisma"
}
}
}
}
}
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
関連レコードがフィルタリング条件に一致する(例:ユーザー名がBobである)すべてのレコードを返します。
例
ユーザー名が"Bob"
であるすべてのPost
レコードを取得
const result = await prisma.post.findMany({
where: {
user: {
is: {
name: "Bob"
},
}
}
}
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'],
},
},
});
set
キーワードを使用せずにtags
を値のリストに設定
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
を使用して、スカラリストフィールドに1つの値または複数の値を追加します。
補足
- 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
少なくとも1つの値がリストに存在する。
例
次のクエリは、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'],
},
},
});
複合型メソッド
MongoDBのみでPrisma 3.10.0
以降で利用可能です。
複合型メソッドを使用すると、複合型を作成、更新、削除できます。
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' }],
},
},
});
複合型フィルター
MongoDBのみでPrisma 3.11.0
以降で利用可能です。
複合型フィルターを使用すると、複合型の内容をフィルタリングできます。
equals
equals
を使用して、複合型または複合型のリストに一致させることで結果をフィルタリングします。複合型のすべての必須フィールドが一致する必要があります。
補足
オプションフィールドを照合する場合、ドキュメントの未定義(欠落)フィールドと、明示的にnull
に設定されたフィールドとを区別する必要があります。
- オプションフィールドを省略すると、未定義のフィールドとは一致しますが、
null
に設定されたフィールドとは一致しません。 - オプションフィールドの
null
値でequals: { ... exampleField: 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
を使用して、リスト内の1つ以上の項目が条件に一致する複合型のリストをフィルタリングします。
例
1つ以上の写真の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
) で利用できます。この機能により、競合状態のリスクなしに、フィールドの現在の値に基づいてフィールドを更新できます (減算や除算など)。
概要: 競合状態
競合状態は、タスクを完了するために2つ以上の操作を順次実行する必要がある場合に発生します。以下の例では、2つのクライアントが同じフィールド (postCount
) を1つ増やそうとします。
クライアント | 操作 | 値 |
---|---|---|
クライアント1 | フィールド値を取得 | 21 |
クライアント2 | フィールド値を取得 | 21 |
クライアント2 | フィールド値を設定 | 22 |
クライアント1 | フィールド値を設定 | 22 ✘ |
値は23
であるべきですが、2つのクライアントはpostCount
フィールドを順番に読み書きしませんでした。更新時のアトミック操作は、読み取りと書き込みを単一の操作に結合し、競合状態を防ぎます。
クライアント | 操作 | 値 |
---|---|---|
クライアント1 | フィールド値を取得して設定 | 21 → 22 |
クライアント2 | フィールド値を取得して設定 | 22 → 23 ✔ |
演算子
オプション | 説明 |
---|---|
increment (インクリメント) | 現在の値にn を追加します。 |
decrement (デクリメント) | 現在の値からn を減算します。 |
multiply (乗算) | 現在の値にn を乗算します。 |
divide (除算) | 現在の値をn で除算します。 |
set (設定) | 現在のフィールド値を設定します。{ myField : n } と同じです。 |
備考
- 1つのクエリにつき、フィールドごとに実行できるアトミック更新は1つだけです。
- フィールドが
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
フィールドの操作」を参照してください。
path
オプションの構文が異なるPostgreSQLとMySQLでサポートされています。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
クライアントメソッドは存在しません。
拡張クライアントでは、クライアントメソッドが必ずしも存在するとは限りません。クライアントを拡張している場合は、$transaction
や$connect
などのクライアントメソッドを使用する前に、存在するかどうかを確認してください。
さらに、$on
または$use
を使用する場合は、これらのメソッドは拡張クライアントには存在しないため、クライアントを拡張する前にこれらのクライアントメソッドを使用する必要があります。特に$use
については、クエリ拡張の使用に移行することをお勧めします。
$disconnect()
$disconnect()
メソッドは、$connect
が呼び出されたときに確立されたデータベース接続を閉じ、Prisma ORMのクエリエンジンを実行していたプロセスを停止します。$connect()
と$disconnect()
の概要については、接続管理を参照してください。
備考
$disconnect()
はPromise
を返すため、async
関数内でawait
キーワードを使用して呼び出す必要があります。
$connect()
$connect()
メソッドは、Prisma ORMのクエリエンジンを介してデータベースへの物理接続を確立します。$connect()
と$disconnect()
の概要については、接続管理を参照してください。
備考
$connect()
はPromise
を返すため、async
関数内でawait
キーワードを使用して呼び出す必要があります。
$on()
拡張クライアントでは$on
は利用できません。クライアント拡張に移行するか、クライアントを拡張する前に$on
メソッドを使用してください。
$on()
メソッドを使用すると、ロギングイベントまたは終了フックを購読できます。
$use()
拡張クライアントでは$use
は利用できません。クエリ拡張に移行するか、クライアントを拡張する前に$use
メソッドを使用してください。
$use()
メソッドはミドルウェアを追加します。
prisma.$use(async (params, next) => {
console.log('This is middleware!');
// Modify or interrogate params here
return next(params);
});
next
next
はミドルウェアスタックにおける「次のレベル」を表します。スタックのどの位置にいるかによって、次のミドルウェアまたはPrisma Queryのいずれかになります。
params
params
は、ミドルウェアで使用する情報を含むオブジェクトです。
パラメータ | 説明 |
---|---|
action (アクション) | クエリのタイプ(例: create またはfindMany )。 |
args (引数) | クエリに渡された引数(例: where 、data 、またはorderBy )。 |
dataPath | fluent 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
参照: Raw SQLの使用 ($queryRawTyped
)。
$queryRaw
$queryRawUnsafe()
参照: Raw SQLの使用 ($queryRawUnsafe()
)。
$executeRaw
$executeRawUnsafe()
参照: Raw SQLの使用 ($executeRawUnsafe()
)。
$runCommandRaw()
参照: Raw SQLの使用 ($runCommandRaw()
)。
$transaction()
参照: トランザクション。
$metrics
Prisma Clientのメトリクスは、Prisma Clientがデータベースとどのようにやり取りしているかについての詳細な洞察を提供します。この洞察は、アプリケーションのパフォーマンス問題を診断するのに役立ちます。詳細はこちら: メトリクス。
Prisma Clientのメトリクスには以下のメソッドがあります。
$metrics.json()
: Prisma ClientのメトリクスをJSON形式で取得します。$metrics.prometheus()
: Prisma ClientのメトリクスをPrometheus形式で取得します。
$extends
$extends
を使用すると、Prisma Client拡張機能を作成および使用して、以下の方法でPrisma Clientに機能を追加できます。
model
: モデルにカスタムメソッドを追加するclient
: クライアントにカスタムメソッドを追加するquery
: カスタムPrisma Clientクエリを作成するresult
: クエリ結果にカスタムフィールドを追加する
詳細はこちら: Prisma Client拡張機能。
ユーティリティ型
ユーティリティ型は、Prisma
名前空間にあるヘルパー関数と型です。アプリケーションのタイプ安全性を維持するのに役立ちます。
Prisma.validator
validator
は、スキーマモデルに基づいて再利用可能なクエリパラメータを作成するのに役立ち、作成するオブジェクトが有効であることを保証します。こちらも参照: Prisma.validator
の使用
validator
を使用する方法は2つあります。
生成された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
プレビュー機能を通じて利用可能でした。
以下の状況では、Rawクエリを使用して同じテーブル内の列を比較する必要があります。
- 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
ステートメントでは、ブール演算子の外側で少なくとも1つのユニークフィールドを指定する必要があり、追加のユニークフィールドおよび非ユニークフィールドはいくつでも指定できます。これを使用して、単一のレコードを返すあらゆる操作にフィルターを追加できます。たとえば、この機能を以下の目的で使用できます。
バージョン4.6.0以降、この機能を使用して、オプションの1対1のネストされた読み取りをフィルタリングできます。
更新時の楽観的並行性制御
update
操作で楽観的並行性制御を実行するために、一意でないフィールドをフィルタリングできます。
楽観的並行性制御を実行するには、コードの実行中にレコードまたは関連レコードのデータが変更されたかどうかを確認するために、version
フィールドを使用することをお勧めします。バージョン4.5.0より前は、version
フィールドが一意でないため、update
操作でversion
フィールドを評価できませんでした。バージョン4.5.0以降では、version
フィールドを評価できます。
以下の例では、updateOne
とupdateTwo
はまず同じレコードを読み取り、次にそれを更新しようとします。データベースは、version
の値が最初の読み取り時と同じ場合にのみ、これらの更新を実行します。データベースがこれらの更新の最初のもの(タイミングによってはupdateOne
またはupdateTwo
になる可能性があります)を実行すると、version
の値が増加します。これは、version
の値が変更されたため、データベースが2番目の更新を実行しないことを意味します。
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
の外側で少なくとも1つのユニークフィールドを指定する必要があります。これらのブール演算子は、フィルター内の他のユニークフィールドまたは非ユニークフィールドと組み合わせて使用できます。
以下の例では、ユニークフィールドである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: { ... }
})
1対1リレーション
バージョン4.5.0以降、1対1リレーションの以下の操作で、一意でないフィールドをフィルタリングできます。
- ネストされた更新
- ネストされたアップサート
- ネストされた切断
- ネストされた削除
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」であり、await
または.then()
または.catch()
を呼び出したときにのみPrismaPromise
が実行されることを意味します。この動作は、すぐに実行を開始する通常の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はすべてのクエリを単一のトランザクションとしてクエリエンジンに渡すことができます。