0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Prismaチートシート(自分用)

Last updated at Posted at 2025-05-06

設定と初期化

インストール

# Prismaと関連パッケージのインストール
npm install prisma @prisma/client
# または
yarn add prisma @prisma/client

初期化

# Prismaの初期化
npx prisma init

環境設定 (.env ファイル)

DATABASE_URL="postgresql://user:password@localhost:5432/mydatabase"

スキーマ定義 (schema.prisma)

基本設定

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

datasource db {
  provider = "postgresql" // または "mysql", "sqlite", "sqlserver"
  url      = env("DATABASE_URL")
}

モデル定義

model User {
  id        Int      @id @default(autoincrement())
  email     String   @unique
  name      String?
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
  posts     Post[]
  profile   Profile?

  @@map("users") // テーブル名をカスタマイズ
}

model Post {
  id        Int      @id @default(autoincrement())
  title     String
  content   String?
  published Boolean  @default(false)
  author    User     @relation(fields: [authorId], references: [id])
  authorId  Int
  tags      Tag[]
  
  @@index([authorId]) // インデックスの作成
}

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

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

リレーションタイプ

// 1対1
model User {
  id      Int     @id
  profile Profile?
}

model Profile {
  id     Int  @id
  user   User @relation(fields: [userId], references: [id])
  userId Int  @unique // @uniqueが必要
}

// 1対多
model User {
  id    Int    @id
  posts Post[]
}

model Post {
  id       Int  @id
  author   User @relation(fields: [authorId], references: [id])
  authorId Int
}

// 多対多
model Post {
  id   Int   @id
  tags Tag[]
}

model Tag {
  id    Int    @id
  posts Post[]
}

マイグレーション管理

マイグレーション作成

# 開発環境用
npx prisma migrate dev --name init

# 名前付きマイグレーション
npx prisma migrate dev --name add_user_profile

マイグレーション適用(本番環境用)

npx prisma migrate deploy

スキーマ更新(既存DBからスキーマを生成)

npx prisma db pull

DBスキーマをPrismaスキーマに合わせる(開発用)

npx prisma db push

マイグレーションのリセット

npx prisma migrate reset

Prisma Client

クライアント生成

npx prisma generate

基本的な使用法

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

async function main() {
  // ここでPrisma操作を実行
}

main()
  .catch(e => {
    console.error(e)
    process.exit(1)
  })
  .finally(async () => {
    await prisma.$disconnect()
  })

CRUD操作

作成(Create)

// 単一レコード作成
const user = await prisma.user.create({
  data: {
    name: '山田太郎',
    email: 'taro@example.com',
  },
})

// リレーションを含む作成
const userWithPosts = await prisma.user.create({
  data: {
    name: '佐藤花子',
    email: 'hanako@example.com',
    posts: {
      create: [
        { title: '初めての投稿', content: '内容...' },
        { title: '2つ目の投稿', content: '内容...' }
      ],
    },
  },
  include: {
    posts: true, // 関連ポストも返す
  },
})

// 複数レコード作成
const users = await prisma.user.createMany({
  data: [
    { name: '鈴木一郎', email: 'ichiro@example.com' },
    { name: '田中二郎', email: 'jiro@example.com' },
  ],
})

読み取り(Read)

// 全件取得
const allUsers = await prisma.user.findMany()

// 条件付き取得
const user = await prisma.user.findUnique({
  where: { id: 1 }
})

const userByEmail = await prisma.user.findUnique({
  where: { email: 'taro@example.com' }
})

// 複合条件
const filteredPosts = await prisma.post.findMany({
  where: {
    AND: [
      { published: true },
      { title: { contains: 'Prisma' } }
    ],
  },
})

// リレーションを含む取得
const usersWithPosts = await prisma.user.findMany({
  include: {
    posts: true,
  },
})

// リレーションの条件付き取得
const usersWithPublishedPosts = await prisma.user.findMany({
  include: {
    posts: {
      where: { published: true }
    }
  }
})

// ネストされたリレーション
const userWithPostsAndProfile = await prisma.user.findUnique({
  where: { id: 1 },
  include: {
    posts: {
      include: {
        tags: true
      }
    },
    profile: true
  }
})

// 選択フィールド
const userNameOnly = await prisma.user.findUnique({
  where: { id: 1 },
  select: { name: true }
})

// ページネーション
const paginatedUsers = await prisma.user.findMany({
  take: 10,  // 10件取得
  skip: 20,  // 20件スキップ
  orderBy: { createdAt: 'desc' }
})

// 集計
const userCount = await prisma.user.count()
const publishedPostCount = await prisma.post.count({
  where: { published: true }
})

更新(Update)

// 単一レコード更新
const updatedUser = await prisma.user.update({
  where: { id: 1 },
  data: { name: '新しい名前' },
})

// 複数レコード更新
const publishAll = await prisma.post.updateMany({
  where: { authorId: 1 },
  data: { published: true },
})

// リレーションを含む更新
const userWithNewPost = await prisma.user.update({
  where: { id: 1 },
  data: {
    posts: {
      create: { title: '新しい投稿' }
    }
  },
  include: { posts: true }
})

// upsert(存在すれば更新、なければ作成)
const upsertUser = await prisma.user.upsert({
  where: { email: 'taro@example.com' },
  update: { name: '山田太郎(更新)' },
  create: { email: 'taro@example.com', name: '山田太郎(新規)' },
})

削除(Delete)

// 単一レコード削除
const deletedUser = await prisma.user.delete({
  where: { id: 1 },
})

// 複数レコード削除
const deleteDrafts = await prisma.post.deleteMany({
  where: { published: false },
})

// カスケード削除(リレーションを含む)
// スキーマで onDelete: Cascade を設定している場合
const deleteUserAndPosts = await prisma.user.delete({
  where: { id: 1 },
})

高度なクエリ

トランザクション

const [newUser, newPost] = await prisma.$transaction([
  prisma.user.create({ 
    data: { name: '新ユーザー', email: 'new@example.com' } 
  }),
  prisma.post.create({ 
    data: { title: '新投稿', authorId: 1 } 
  })
])

// インタラクティブなトランザクション
const result = await prisma.$transaction(async (tx) => {
  const user = await tx.user.findUnique({ where: { id: 1 } })
  if (!user) throw new Error('ユーザーが見つかりません')
  
  const post = await tx.post.create({
    data: { title: 'タイトル', authorId: user.id }
  })
  
  return { user, post }
})

Raw SQL

// 直接SQLを実行
const result = await prisma.$queryRaw`SELECT * FROM users WHERE id = ${userId}`

// 型付きクエリ
const result = await prisma.$queryRaw<User[]>`SELECT * FROM users`

シード

シードスクリプト (prisma/seed.ts)

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

async function main() {
  // データクリーンアップ
  await prisma.post.deleteMany()
  await prisma.user.deleteMany()
  
  // データ作成
  const user = await prisma.user.create({
    data: {
      name: 'テストユーザー',
      email: 'test@example.com',
      posts: {
        create: [
          { title: 'テスト投稿1', published: true },
          { title: 'テスト投稿2', published: false },
        ]
      }
    }
  })
  
  console.log('シード完了', user)
}

main()
  .catch(e => console.error(e))
  .finally(async () => await prisma.$disconnect())

package.json 設定

{
  "prisma": {
    "seed": "ts-node prisma/seed.ts"
  }
}

シード実行

npx prisma db seed

Prisma Studio(GUI)

npx prisma studio

ミドルウェア

const prisma = new PrismaClient()

// ロギングミドルウェア
prisma.$use(async (params, next) => {
  console.log(`操作: ${params.model}.${params.action}`)
  const before = Date.now()
  const result = await next(params)
  const after = Date.now()
  console.log(`時間: ${after - before}ms`)
  return result
})

デバッグとログ

const prisma = new PrismaClient({
  log: ['query', 'info', 'warn', 'error'],
})

// または特定のレベルのみ
const prisma = new PrismaClient({
  log: [
    { emit: 'stdout', level: 'query' },
    { emit: 'event', level: 'error' },
  ],
})

// イベントリスナー
prisma.$on('query', (e) => {
  console.log('クエリ: ' + e.query)
  console.log('パラメータ: ' + e.params)
  console.log('実行時間: ' + e.duration + 'ms')
})

script

環境構築

# Dockerコンテナのビルドと起動
docker compose up -d --build

# Prisma Clientの生成
docker compose exec app npm run prisma:generate
prisma generate --schema ./src/prisma/schema.prisma

# 初期マイグレーションの実行
docker compose exec app npm run prisma:migrate-dev -- --name init
prisma migrate dev --schema ./src/prisma/schema.prisma

# シードデータの投入
docker compose exec app npm run prisma:seed
prisma db seed --schema ./src/prisma/schema.prisma

スキーマ変更関連

# 新しいマイグレーションの作成と実行(スキーマ変更後)
docker compose exec app npm run prisma:migrate-dev -- --name [変更内容を表す名前]
prisma migrate dev --schema ./src/prisma/schema.prisma

# 例: テーブル追加
docker compose exec app npm run prisma:migrate-dev -- --name add_categories_table

# 例: カラム追加
docker compose exec app npm run prisma:migrate-dev -- --name add_image_url_to_posts

シードデータ関連

# シードデータの投入
docker compose exec app npm run prisma:seed
prisma db seed --schema ./src/prisma/schema.prisma

# データベースをリセット(マイグレーションを再適用し、シードデータを投入)
docker compose exec app npx prisma migrate reset --force --schema ./src/prisma/schema.prisma

確認・デバッグ

# データの確認(Prisma Studio起動)
docker compose exec app npm run prisma:studio
prisma studio --schema ./src/prisma/schema.prisma --hostname 0.0.0.0

# PostgreSQLへのアクセス
npm run psql
docker exec -it prisma_docker_starter_db psql -U user -d mydatabase

# データベース構造の確認(PostgreSQLコンソール内)
\dt
\d sample_table
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?