メインコンテンツにスキップ

CRUD

このページでは、生成された Prisma Client API を使って CRUD 操作を実行する方法について説明します。CRUD は、以下の頭文字を取った略語です。

各メソッドの詳細については、Prisma Client API リファレンスドキュメントを参照してください。

スキーマ例

すべての例は以下のスキーマに基づいています。

サンプルスキーマを展開
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}

generator client {
provider = "prisma-client-js"
}

model ExtendedProfile {
id Int @id @default(autoincrement())
biography String
user User @relation(fields: [userId], references: [id])
userId Int @unique
}

model User {
id Int @id @default(autoincrement())
name String?
email String @unique
profileViews Int @default(0)
role Role @default(USER)
coinflips Boolean[]
posts Post[]
profile ExtendedProfile?
}

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)
categories Category[]
}

model Category {
id Int @id @default(autoincrement())
name String @unique
posts Post[]
}

enum Role {
USER
ADMIN
}

リレーショナルデータベースの場合、db push コマンドを使用して、サンプルスキーマを独自のデータベースにプッシュします。

npx prisma db push

MongoDBの場合、データが均一な形式であり、Prisma スキーマで定義されたモデルと一致していることを確認してください。

作成

単一レコードの作成

以下のクエリは、2 つのフィールドを持つ単一のユーザーを作成します (create())。

const user = await prisma.user.create({
data: {
email: 'elsa@prisma.io',
name: 'Elsa Prisma',
},
})
表示クエリ結果

ユーザーの id は自動生成され、どのフィールドが必須であるかはスキーマによって決定されます。

生成された型を使用した単一レコードの作成

以下の例は同じ結果を生成しますが、create() クエリのコンテキスト**外**で UserCreateInput 型の変数 user を作成します。簡単なチェック(「この create() クエリに投稿を含めるべきか?」)を完了した後、user 変数はクエリに渡されます。

import { PrismaClient, Prisma } from '@prisma/client'

const prisma = new PrismaClient()

async function main() {
let includePosts: boolean = false
let user: Prisma.UserCreateInput

// Check if posts should be included in the query
if (includePosts) {
user = {
email: 'elsa@prisma.io',
name: 'Elsa Prisma',
posts: {
create: {
title: 'Include this post!',
},
},
}
} else {
user = {
email: 'elsa@prisma.io',
name: 'Elsa Prisma',
}
}

// Pass 'user' object into query
const createUser = await prisma.user.create({ data: user })
}

main()

生成された型の操作の詳細については、生成された型を参照してください。

複数レコードの作成

Prisma Client は、2.20.0 以降で、GA (一般提供) 機能として一括挿入をサポートしています。

以下の createMany() クエリは複数のユーザーを作成し、重複するレコード (email は一意でなければなりません) をスキップします。

const createMany = await prisma.user.createMany({
data: [
{ name: 'Bob', email: 'bob@prisma.io' },
{ name: 'Bobo', email: 'bob@prisma.io' }, // Duplicate unique key!
{ name: 'Yewande', email: 'yewande@prisma.io' },
{ name: 'Angelique', email: 'angelique@prisma.io' },
],
skipDuplicates: true, // Skip 'Bobo'
})
表示クエリ結果
{
count: 3
}
警告

MongoDB、SQLServer、または SQLite を使用している場合、skipDuplicates はサポートされていません。

createMany() は、複数の値を持つ単一の INSERT INTO ステートメントを使用します。これは、行ごとに個別の INSERT を実行するよりも一般的に効率的です。

BEGIN
INSERT INTO "public"."User" ("id","name","email","profileViews","role","coinflips","testing","city","country") VALUES (DEFAULT,$1,$2,$3,$4,DEFAULT,DEFAULT,DEFAULT,$5), (DEFAULT,$6,$7,$8,$9,DEFAULT,DEFAULT,DEFAULT,$10), (DEFAULT,$11,$12,$13,$14,DEFAULT,DEFAULT,DEFAULT,$15), (DEFAULT,$16,$17,$18,$19,DEFAULT,DEFAULT,DEFAULT,$20) ON CONFLICT DO NOTHING
COMMIT
SELECT "public"."User"."country", "public"."User"."city", "public"."User"."email", SUM("public"."User"."profileViews"), COUNT(*) FROM "public"."User" WHERE 1=1 GROUP BY "public"."User"."country", "public"."User"."city", "public"."User"."email" HAVING AVG("public"."User"."profileViews") >= $1 ORDER BY "public"."User"."country" ASC OFFSET $2

: $transaction 内で複数の create() ステートメントを実行すると、複数の INSERT ステートメントが生成されます。

以下のビデオでは、createMany()faker.js を使用して、データベースにサンプルデータをシードする方法をデモンストレーションしています。

レコードと、1 つ以上の関連レコードを同時に作成する方法については、リレーションの操作 > ネストされた書き込みを参照してください。

複数レコードの作成と返却

情報

この機能は、Prisma ORM バージョン 5.14.0 以降で PostgreSQL、CockroachDB、および SQLite で利用可能です。

createManyAndReturn() を使用すると、複数のレコードを作成し、その結果のオブジェクトを返すことができます。

const users = await prisma.user.createManyAndReturn({
data: [
{ name: 'Alice', email: 'alice@prisma.io' },
{ name: 'Bob', email: 'bob@prisma.io' },
],
})
表示クエリ結果
警告

createManyAndReturn() を使用する場合、relationLoadStrategy: join は利用できません。

読み取り

ID または一意の識別子によるレコードの取得

以下のクエリは、一意の識別子または ID によって単一のレコードを返します (findUnique())。

// By unique identifier
const user = await prisma.user.findUnique({
where: {
email: 'elsa@prisma.io',
},
})

// By ID
const user = await prisma.user.findUnique({
where: {
id: 99,
},
})

MongoDB コネクタを使用しており、基になる ID の型が ObjectId の場合、その ObjectId の文字列表現を使用できます。

// By ID
const user = await prisma.user.findUnique({
where: {
id: '60d5922d00581b8f0062e3a8',
},
})

全レコードの取得

以下の findMany() クエリは、**すべて**の User レコードを返します。

const users = await prisma.user.findMany()

結果をページ分割することもできます。

特定の条件に一致する最初のレコードの取得

以下の findFirst() クエリは、100 以上の「いいね!」がある投稿を少なくとも 1 つ持つ、**最も新しく作成されたユーザー**を返します。

  1. ユーザーをIDの降順(大きい順)で並べ替える - 最大のIDが最新です。
  2. 100以上の「いいね!」がある投稿を少なくとも1つ持つユーザーを降順で最初のユーザーとして返します。
const findUser = await prisma.user.findFirst({
where: {
posts: {
some: {
likes: {
gt: 100,
},
},
},
},
orderBy: {
id: 'desc',
},
})

レコードのフィルタリングされたリストの取得

Prisma Client は、レコードフィールドおよび関連レコードフィールドでのフィルタリングをサポートしています。

単一のフィールド値によるフィルタリング

以下のクエリは、メールアドレスが "prisma.io" で終わるすべての User レコードを返します。

const users = await prisma.user.findMany({
where: {
email: {
endsWith: 'prisma.io',
},
},
})

複数のフィールド値によるフィルタリング

以下のクエリは、演算子の組み合わせを使用して、名前が E で始まる**または**プロフィール閲覧数が 1 以上の管理者であるユーザーを返します。

const users = await prisma.user.findMany({
where: {
OR: [
{
name: {
startsWith: 'E',
},
},
{
AND: {
profileViews: {
gt: 0,
},
role: {
equals: 'ADMIN',
},
},
},
],
},
})

以下のクエリは、メールアドレスが prisma.io で終わり、**かつ**公開されていない投稿 (some) が少なくとも**1つ**あるユーザーを返します。

const users = await prisma.user.findMany({
where: {
email: {
endsWith: 'prisma.io',
},
posts: {
some: {
published: false,
},
},
},
})

関連フィールド値のフィルタリングのその他の例については、リレーションの操作を参照してください。

フィールドのサブセットの選択

以下の findUnique() クエリは、select を使用して、特定の User レコードの email および name フィールドを返します。

const user = await prisma.user.findUnique({
where: {
email: 'emma@prisma.io',
},
select: {
email: true,
name: true,
},
})
表示クエリ結果

リレーションの含め方について、詳しくは以下を参照してください。

以下のクエリは、ネストされた select を使用して以下を返します。

  • ユーザーの email
  • 各投稿の likes フィールド
const user = await prisma.user.findUnique({
where: {
email: 'emma@prisma.io',
},
select: {
email: true,
posts: {
select: {
likes: true,
},
},
},
})
表示クエリ結果

リレーションの含め方について、詳しくはフィールドの選択とリレーションの含め方を参照してください。

異なるフィールド値の選択

異なるフィールド値の選択については、distinct の選択を参照してください。

以下のクエリは、すべての ADMIN ユーザーを返し、結果に各ユーザーの投稿を含めます。

const users = await prisma.user.findMany({
where: {
role: 'ADMIN',
},
include: {
posts: true,
},
})
表示クエリ結果

リレーションの含め方について、詳しくはフィールドの選択とリレーションの含め方を参照してください。

関連のフィルタリングされたリストを含める

includewhere を組み合わせて、フィルタリングされたリレーションのリスト (例: ユーザーの公開済み投稿のみを含める) を取得する方法については、リレーションの操作を参照してください。

更新

単一レコードの更新

以下のクエリは、update() を使用して、email で単一の User レコードを検索し、更新します。

const updateUser = await prisma.user.update({
where: {
email: 'viola@prisma.io',
},
data: {
name: 'Viola the Magnificent',
},
})
表示クエリ結果

複数レコードの更新

以下のクエリは、updateMany() を使用して、prisma.io を含むすべての User レコードを更新します。

const updateUsers = await prisma.user.updateMany({
where: {
email: {
contains: 'prisma.io',
},
},
data: {
role: 'ADMIN',
},
})
表示クエリ結果

複数レコードの更新と返却

情報

この機能は、Prisma ORM バージョン 6.2.0 以降で PostgreSQL、CockroachDB、および SQLite で利用可能です。

updateManyAndReturn() を使用すると、複数のレコードを更新し、その結果のオブジェクトを返すことができます。

const users = await prisma.user.updateManyAndReturn({
where: {
email: {
contains: 'prisma.io',
}
},
data: {
role: 'ADMIN'
}
})
表示クエリ結果
警告

updateManyAndReturn() を使用する場合、relationLoadStrategy: join は利用できません。

レコードの更新**または**作成

以下のクエリは、upsert() を使用して、特定のメールアドレスを持つ User レコードを更新するか、存在しない場合はその User レコードを作成します。

const upsertUser = await prisma.user.upsert({
where: {
email: 'viola@prisma.io',
},
update: {
name: 'Viola the Magnificent',
},
create: {
email: 'viola@prisma.io',
name: 'Viola the Magnificent',
},
})
表示クエリ結果
情報

バージョン 4.6.0 から、Prisma Client は可能な限りデータベースネイティブの SQL コマンドで upsert を実行します。詳細はこちら

Prisma Client には findOrCreate() クエリがありません。代わりに upsert() を使用できます。upsert()findOrCreate() メソッドのように動作させるには、upsert() に空の update パラメータを指定します。

警告

upsert()findOrCreate() の回避策として使用する場合の制限は、upsert()where 条件で一意のモデルフィールドのみを受け入れることです。そのため、where 条件に一意でないフィールドが含まれている場合、upsert() を使用して findOrCreate() をエミュレートすることはできません。

数値フィールドの更新

数値フィールドを**現在の値に基づいて**更新するには、アトミック数値操作を使用します(例:増分または乗算)。以下のクエリは、viewslikes フィールドを 1 ずつ増分します。

const updatePosts = await prisma.post.updateMany({
data: {
views: {
increment: 1,
},
likes: {
increment: 1,
},
},
})

関連レコードの切断 (disconnect) および接続 (connect) については、リレーションの操作を参照してください。

削除

単一レコードの削除

以下のクエリは、delete() を使用して、単一の User レコードを削除します。

const deleteUser = await prisma.user.delete({
where: {
email: 'bert@prisma.io',
},
})

1 つ以上の投稿を持つユーザーを削除しようとするとエラーが発生します。これは、すべての Post に作成者が必要であるためです。詳細については、カスケード削除を参照してください。

複数レコードの削除

以下のクエリは、deleteMany() を使用して、emailprisma.io を含むすべての User レコードを削除します。

const deleteUsers = await prisma.user.deleteMany({
where: {
email: {
contains: 'prisma.io',
},
},
})

1 つ以上の投稿を持つユーザーを削除しようとするとエラーが発生します。これは、すべての Post に作成者が必要であるためです。詳細については、カスケード削除を参照してください。

全レコードの削除

以下のクエリは、deleteMany() を使用して、すべての User レコードを削除します。

const deleteUsers = await prisma.user.deleteMany({})

このクエリは、ユーザーに関連レコード(投稿など)がある場合、失敗することに注意してください。この場合、最初に関連レコードを削除する必要があります。

警告

2.26.0 以降では、**プレビュー機能**の参照アクションを使用してカスケード削除を行うことができます。

以下のクエリは、delete() を使用して、単一の User レコードを削除します。

const deleteUser = await prisma.user.delete({
where: {
email: 'bert@prisma.io',
},
})

ただし、例のスキーマには PostUser の間に**必須のリレーション**が含まれており、これは投稿があるユーザーを削除できないことを意味します。

The change you are trying to make would violate the required relation 'PostToUser' between the `Post` and `User` models.

このエラーを解決するには、次のいずれかの方法があります。

  • リレーションをオプションにする

    model Post {
    id Int @id @default(autoincrement())
    author User? @relation(fields: [authorId], references: [id])
    authorId Int?
    author User @relation(fields: [authorId], references: [id])
    authorId Int
    }
  • ユーザーを削除する前に、投稿の作者を別のユーザーに変更する。

  • トランザクション内で2つの個別のクエリ(すべてのクエリが成功する必要がある)を使って、ユーザーとそのすべての投稿を削除する。

    const deletePosts = prisma.post.deleteMany({
    where: {
    authorId: 7,
    },
    })

    const deleteUser = prisma.user.delete({
    where: {
    id: 7,
    },
    })

    const transaction = await prisma.$transaction([deletePosts, deleteUser])

すべてのテーブルからすべてのレコードを削除

時には、すべてのテーブルからすべてのデータを削除したいが、実際のテーブルは残したいという場合があります。これは、開発環境やテスト中に特に役立ちます。

以下に、Prisma Client と Prisma Migrate を使用して、すべてのテーブルからすべてのレコードを削除する方法を示します。

deleteMany() を使用してすべてのデータを削除する

テーブルの削除順序が分かっている場合、deleteMany 関数を使用できます。これは $transaction 内で同期的に実行され、あらゆる種類のデータベースで使用できます。

const deletePosts = prisma.post.deleteMany()
const deleteProfile = prisma.profile.deleteMany()
const deleteUsers = prisma.user.deleteMany()

// The transaction runs synchronously so deleteUsers must run last.
await prisma.$transaction([deleteProfile, deletePosts, deleteUsers])

長所

  • スキーマの構造を事前に把握している場合にうまく機能します
  • 各テーブルのデータを同期的に削除します

短所

  • リレーショナルデータベースを使用する場合、この関数は、リレーショナル制約に関係なくテーブルをルックアップして TRUNCATE する、より汎用的なソリューションよりもスケールしません。このスケーリングの問題は、MongoDB コネクタを使用する場合には適用されないことに注意してください。

: $transaction は各モデルのテーブルでカスケード削除を実行するため、順序通りに呼び出す必要があります。

生の SQL / TRUNCATE を使用してすべてのデータを削除する

生の SQL の扱いに慣れている場合、$executeRawUnsafe を使用してテーブルに対して TRUNCATE クエリを実行できます。

以下の例では、最初のタブは、Postgres データベースで $queryRaw ルックアップを使用して TRUNCATE を実行する方法を示しています。これはテーブルをマッピングし、単一のクエリですべてのテーブルを TRUNCATE します。

2番目のタブは、同じ関数を MySQL データベースで実行する方法を示しています。この場合、TRUNCATE を実行する前に制約を削除し、完了後に元に戻す必要があります。プロセス全体は $transaction として実行されます。

const tablenames = await prisma.$queryRaw<
Array<{ tablename: string }>
>`SELECT tablename FROM pg_tables WHERE schemaname='public'`

const tables = tablenames
.map(({ tablename }) => tablename)
.filter((name) => name !== '_prisma_migrations')
.map((name) => `"public"."${name}"`)
.join(', ')

try {
await prisma.$executeRawUnsafe(`TRUNCATE TABLE ${tables} CASCADE;`)
} catch (error) {
console.log({ error })
}

長所

  • スケーラブル
  • 非常に高速

短所

  • 操作を元に戻すことはできません
  • 予約されている SQL キーワードをテーブル名として使用すると、生のクエリを実行しようとしたときに問題が発生する可能性があります。

Prisma Migrate を使用した全レコードの削除

Prisma Migrate を使用している場合、migrate reset を使用できます。これは以下の操作を行います。

  1. データベースを削除
  2. 新しいデータベースを作成
  3. マイグレーションを適用
  4. データベースにデータをシード

高度なクエリ例

深くネストされたレコードツリーを作成

  • 単一の User
  • 新しく関連付けられた Post レコード2件
  • 投稿ごとに Category を接続または作成
const u = await prisma.user.create({
include: {
posts: {
include: {
categories: true,
},
},
},
data: {
email: 'emma@prisma.io',
posts: {
create: [
{
title: 'My first post',
categories: {
connectOrCreate: [
{
create: { name: 'Introductions' },
where: {
name: 'Introductions',
},
},
{
create: { name: 'Social' },
where: {
name: 'Social',
},
},
],
},
},
{
title: 'How to make cookies',
categories: {
connectOrCreate: [
{
create: { name: 'Social' },
where: {
name: 'Social',
},
},
{
create: { name: 'Cooking' },
where: {
name: 'Cooking',
},
},
],
},
},
],
},
},
})
© 2025 prisma.dokyumento.jp. All rights reserved.