ORM として Prisma を利用した Next.js アプリからあらかじめテーブルが存在する PlanetScale 上の MySQL データベースに対して接続するまでの流れをメモ

see also: Add Prisma to an existing project that uses a relational database (15 min) : typescript-postgresql | Prisma Docs

Prisma の基本的な利用方法

データベーススキーマのインポート

  • yarn add -D prisma で Next.js アプリに Prisma を導入
  • yarn prisma init を実行すると Prisma の利用に必要なファイルが生成される
  • 生成された .env ファイルの DATABASE_URL に PlanetScale のデータベース接続情報を入力する
    • URL 末尾に ?sslaccept=strict をつける必要がある点に注意
  • yarn prisma db pull を実行するとスキーマのインポートが完了する
    • prisma/schema.prisma にインポートされたスキーマの情報が保持される

クライアントコードの組み込み

  • yarn add @prisma/client で Prisma クライアントライブラリを導入
  • yarn prisma generate でクライアントコードを生成

上記の状態で例えば以下のようなサーバーコンポーネントを作成しページにアクセスすると DB から取得したレコードがログ出力される

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

export const Test = async () => {
  const res = await prisma.artists.findFirst()
  console.log(res)
  return (
    <div>
      <h1>Test</h1>
    </div>
  )
}

複数のテーブルが絡むクエリを行いたい

see also: Relation queries (Concepts) | Prisma Docs

const songs = await prisma.songs.findMany({
  select: {
    id: true,
    slug: true,
    title: true,
    song_credits: {
      select: {
        name: true,
        role: true,
      },
      where: {
        role: {
          in: ['Lyrics', 'Music', 'Arrangement'],
        },
      },
    },
  },
  orderBy: { kana: 'asc' },
  take: 20,
})

Q&A

Next.js において PrismaClient をどのように取り扱うか

see also: Best practices for using Prisma Client with Next.js | Prisma Docs

Next.js にて各ページやコンポーネントに PrismaClient を定義していると下記のような警告が出ることがある。特に開発時に頻繁に hot reload しているとあっというまに Connection を使い果たしてしまう。

warn(prisma-client) There are already 10 instances of Prisma Client actively running.

Prisma 公式に提案されている解決策としては単純に下記のようにグローバルにシングルトンな PrismaClient を持つという形となる。

import { PrismaClient } from '@prisma/client'

const prismaClientSingleton = () => {
  return new PrismaClient()
}

declare global {
  var prisma: undefined | ReturnType<typeof prismaClientSingleton>
}

const prisma = globalThis.prisma ?? prismaClientSingleton()

export default prisma

if (process.env.NODE_ENV !== 'production') globalThis.prisma = prisma

Next.js の unstable_cache で Date, DateTime 型を含むデータのキャッシュに失敗する

known Issue: unstable_cache does not deserialize dates · Issue #51613 · vercel/next.js

prisma generate したあとの型定義の反映に VSCode の再起動が必要

known issue: prisma generate, typings not updating in VSCode unless IDE is restarted. · Issue #14722 · prisma/prisma

Copyright © 53ningen.com