💻

Prisma でテーブルを作成

2023/10/18に公開

経緯

フロントエンドベースでDB操作を行えるPrismaを勉強中のため、実際にPrismaを使用してテーブル作成、seed.tsでデータ投入までを実施しながら、使用方法を学んでみた。

概要

Prismaを使用し、スキーマを作成することで必要なモデル・テーブルを生成。
seed.tsを使用して、作成したテーブルにデータを投入。

Prismaを使用してテーブルを作成

1. Prismaのインストール

1) prismaインストール

pnpm i -D prisma

2) 初期化

pnpm prisma init

■初期化すると以下のファイルが作成される

  • .env
  • prisma/schema.prisma
$ tree -a -I node_modules

.
├── .env <-- 新規生成
・・・
├── Docker-compose.yml
├── Dockerfile
├── app
・・・
├── package.json
├── postcss.config.js
├── prisma <-- 新規生成
│   └── schema.prisma <-- 新規生成
・・・
└── tsconfig.json

2. データベースの準備

1) Docker-compose.ymlの設定

前回作成したDocker-compose.ymlの設定をそのまま使用する
※ 前回記事も見てみてください!
前回記事:Dockerでpostgresqlを構築する

Docker-compose.yml
version: '3'

services:
  db:
    image: postgres:14
    container_name: postgres_test
    ports:
      - 5432:5432
    volumes:
      - db-store:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: 'user'
      POSTGRES_PASSWORD: 'postgres'
volumes:
  db-store:

2) Dockerコンテナを起動

以下コマンドで、Dockerコンテナを起動

docker compose up -d

3. DB への接続情報を設定

1) schema.prismaの設定

prisma/schema.prismaはデータベースの情報やデータモデル(テーブル構造)を記述

schema.prismaにデータモデルを追記してみる

prisma/schema.prisma
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

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

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

// add start
model User {
  id           String    @id @default(uuid())
  username     String? 
  email        String?   @unique
  password     String
  createdAt    DateTime  @default(now()) @map("created_at")
  updatedAt    DateTime  @updatedAt @map("updated_at")
}
// add end

■設定内容

  • db provider:postgresql
  • client:prisma-client-js
  • モデル:ここのみ追加。今回はUserテーブルのモデルを追記。

2) .envの設定

.envには、DATABASE_URLを設定する
前回作成したDocker-compose.ymlの設定を確認しつつ設定

.env
# Environment variables declared in this file are automatically made available to Prisma.
# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema

# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings

# 初期設定
# DATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public"

# 修正後
DATABASE_URL="postgresql://user:postgres@localhost:5432/mydb?schema=public"

■設定内容

  • db provider:postgresql
  • ユーザ名:user
  • パスワード:postgres
  • ホスト:localhost
  • ポート:5432
  • DB名:mydb
  • スキーマ:public(任意)

4. マイグレーションの作成・実行

1) マイグレーションを実行

  • SQL作成・DBへ反映・型情報の生成
pnpm prisma migrate dev

■マイグレーションを実行すると以下のファイルが作成され、マイグレーションが管理されるようになる
マイグレーションの管理は DB の_prisma_migrationsテーブルで行われ、そこに実行したマイグレーションの記録が格納されている

  • prisma/migrations/20210622135843_init/migration.sql
  • prisma/migrations/migration_lock.toml
$ tree -a -I node_modules 

.
├── .env
・・・
├── Docker-compose.yml
├── Dockerfile
├── app
・・・
├── package.json
├── postcss.config.js
├── prisma
│   ├── migrations <・・・ 新規生成
│   │   ├── 20231018011646_init <-- 新規生成
│   │   │   └── migration.sql <-- 新規生成 
│   │   └── migration_lock.toml <-- 新規生成
│   └── schema.prisma
・・・
└── tsconfig.json
migration.sql
-- CreateTable
CREATE TABLE "User" (
    "id" TEXT NOT NULL,
    "username" TEXT,
    "email" TEXT,
    "password" TEXT NOT NULL,
    "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updated_at" TIMESTAMP(3) NOT NULL,

    CONSTRAINT "User_pkey" PRIMARY KEY ("id")
);

-- CreateIndex
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");

2) TablePlusで接続確認

  • DB接続情報を設定すると接続可能
     
  • Userテーブルが生成され、カラムも設定内容通りに作成されていることを確認

5. Prisma Clientの生成

schema.prismaのスキーマ情報に沿ったクライアントを生成する。
生成コマンドを叩くことで、Prisma schemaを読み、Prisma Clientコードを作成・更新する。
生成されたコードはnode_modules/@prisma/clientに置かれ、使用する際はここからインポートする。

pnpm prisma generate   
実行結果
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma

✔ Generated Prisma Client (v5.4.2) to ./node_modules/@prisma/client in 61ms

Start using Prisma Client in Node.js (See: https://pris.ly/d/client)
``
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
``
or start using Prisma Client at the edge (See: https://pris.ly/d/accelerate)
``
import { PrismaClient } from '@prisma/client/edge'
const prisma = new PrismaClient()
``

See other ways of importing Prisma Client: http://pris.ly/d/importing-client

seed.tsを使用してデータ投入

1. prisma ディレクトリにseed.jsファイルを作成する。

今回はdevディレクトリを作成し、その配下にseed.jsファイルを作成

├── prisma
│   ├── dev <--作成
│   │   └── seed.ts <--作成
│   ├── migrations
│   │   ├── 20231018011646_init
│   │   └── migration_lock.toml
│   └── schema.prisma
seed.ts
import { PrismaClient } from '@prisma/client'
import { Prisma } from '@prisma/client'

const prisma = new PrismaClient()

// 投入するデータ定義
const userData: Prisma.UserCreateInput[] = [
    {
        username: 'user3',
        email: 'user3@example.com',
        password: 'password3'
    },
    {
        username: 'user4',
        email: 'user4@example.com',
        password: 'password4'
    }
]
const transfer = async () => {
    const users = [];
    for (const u of userData) {
        const user = prisma.user.create({
            data: u,
        })
        users.push(user);
    }
    return await prisma.$transaction(users);
}

// 定義されたデータを実際のモデルへ登録する処理
const main = async () => {
    console.log(`Start seeding ...`)

    await transfer();

    console.log(`Seeding finished.`)
}

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

2. パッケージのイントール

typescript, ts-nodeと@types/nodeをインストールする

npm install -D typescript ts-node @types/node

3. package.jsonに以下を追加

package.jsonにseedコマンドを追加する

package.json
 "prisma": {
    "seed": "ts-node --compiler-options {\"module\":\"CommonJS\"} prisma/dev/seed.ts"
  }

ちなみにtsconfig.jsonは以下設定

tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "CommonJS",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  },
  "include": [
    "src"
  ]
}

4. seedコマンド実行

npx prisma db seed    

以下の結果であればOK

実行結果
Environment variables loaded from .env
Running seed command `ts-node --compiler-options {"module":"CommonJS"} prisma/dev/seed.ts` ...
Start seeding ...
Seeding finished.

🌱  The seed command has been executed.

5.データが投入されていることを確認

おわりに

データ投入では、seed.tsを使用してみましたが、参考資料ごとにコマンドが異なっていたりとやり方は様々でした。
参考資料のままに作成して動いたというような状態のため、まだまだ勉強は必要です。
faker.jsを使用したデータ投入についてもやってみたいと思っています φ(. . )

参考

https://zenn.dev/farstep/books/7a6eb67dd3bf1f/viewer/ba0cb7
https://qiita.com/dkawabata/items/cafa3dc53921db520360
https://zenn.dev/koheii/books/8cdd27e7a82abc/viewer/a84c9f

Discussion