コンテンツにスキップ

Prisma@SQLパッケージ

はじめに

本サイトにつきまして、以下をご認識のほど宜しくお願いいたします。


01. Prismaの仕組み

PrismaClient (JavaScriptパッケージ) は、クエリエンジン (バイナリ) に接続リクエストを送信する。

クエリエンジンはコネクションプールを作成し、プール内のコネクションを使用してDBに接続する。

コネクションが維持されている間、これを再利用して複数のクエリを実行する。

PrismaClientは、クエリエンジンに切断リクエストを送信する。

クエリエンジンは、データベースとのコネクションを破棄する。

architecture_prisma


02. コマンド

generate

Prismaスキーマからクライアントを作成する。

クライアントを使用して、データベースに接続できる。

マイグレーションや初期データを挿入前に必要である。

$ yarn prisma generate

✔ Generated Prisma Client (4.16.2 | library) to ./node_modules/@prisma/client in 177ms
You can now start using Prisma Client in your code. Reference: https://pris.ly/d/client

import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()


migrate

▼ dev

ローカル環境用のマイグレーションを実行する。

$ yarn prisma migrate dev


db

▼ seed

ローカル環境用の初期データを挿入する。

$ yarn prisma db seed


03. スキーマ

datasource

▼ datasourceとは

データベース情報を設定する。

▼ url

プロトコル名として、mysqlpostgresqlを設定できる。

datasource db {
  provider = "<プロトコル名>"
  url      = "<プロトコル名>://<DBユーザー>:<DBパスワード>@<DBホスト>:<ポート番号>/<DB名>?schema=public&connection_limit=30&pool_timeout=60"
}

▼ urlパラメーター

URLのパラメーターとして、以下などを設定できる。

  • コネションプールのコネクション上限数 (connection_limit)
  • コネクションプール内のコネクションが空くまでの待機時間 (pool_timeout)


generator

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


04. PrismaClient

$transaction

▼ $transaction

複数のクエリ処理を実行するトランザクションを定義する。

import {PrismaClient} from '@prisma/client'

const prisma = new PrismaClient()

function transfer(from: string, to: string, amount: number) {

  // トランザクション
  return prisma.$transaction(async (tx) => {

    // CRUD処理
    const sender = await tx.account.update({
      data: {
        balance: {
          decrement: amount,
        },
      },
      where: {
        email: from,
      },
    })

    if (sender.balance < 0) {
      throw new Error(`${from} doesn't have enough to send ${amount}`)
    }

    // CRUD処理
    const recipient = await tx.account.update({
      data: {
        balance: {
          increment: amount,
        },
      },
      where: {
        email: to,
      },
    })

    return recipient
  })
}

async function main() {

  // $transaction関数の実行をtry-catchブロックで囲む
  try {
    await transfer('alice@prisma.io', 'bob@prisma.io', 100)
    await transfer('alice@prisma.io', 'bob@prisma.io', 100)
  } catch (err) {

  }
}

main()

▼ オプション

import {PrismaClient} from '@prisma/client'

// Prismaクライアントに設定する場合
const prisma = new PrismaClient({
  transactionOptions: {
    // データを取得するまでのタイムアウト値
    maxWait: 5000,
    // ロールバックを含めて全体が完了するまでのタイムアウト値
    timeout: 10000,
    // トランザクションの分離レベル
    isolationLevel: Prisma.TransactionIsolationLevel.Serializable,
  }
})

function transfer(...) {

  return prisma.$transaction(async (tx) => {
    // CRUD処理
  })
}

async function main() {

  try {
    await transfer(...)
  } catch (err) {

  }
}

main()
import {PrismaClient} from '@prisma/client'

const prisma = new PrismaClient()

function transfer(...) {

  // トランザクションに個別に設定する場合
  return prisma.$transaction(async (tx) => {
    // CRUD処理
  },
  {
    // データを取得するまでのタイムアウト値
    maxWait: 5000,
    // ロールバックを含めて全体が完了するまでのタイムアウト値
    timeout: 10000,
    // トランザクションの分離レベル
    isolationLevel: Prisma.TransactionIsolationLevel.Serializable,
  })
}

async function main() {

  try {
    await transfer(...)
  } catch (err) {

  }
}

main()