VSCode で schema.prisma ファイルを書く

VSCode で schema.prisma ファイルを書く時までの手順と役に立ったツールをご紹介します。  
筆者は Prisma を使い始めたばかりの初心者ですので、ご了承ください。

## 本記事のスコープ

schema.prisma ファイルを記述して、DB にテーブルを作成するまでを対象とします。
アプリケーションの実装は対象外です。

## 前提

今回は以下の環境で Prisma を使用することを前提とします。

| 項目                 |            |
| -------------------- | ---------- |
| 言語                 | TypeScript |
| フレームワーク       | NestJS     |
| DBMS                 | PostgreSQL |
| IDE                  | VSCode     |
| パッケージ管理ツール | npm        |

## Prisma とは

[prisma](https://www.prisma.io/) は Node.js で使用されるオープンソースの ORM です。

## 手順

初期設定から DB にテーブルを作成するまでの手順を説明します。  
NestJS の[ドキュメント](https://docs.nestjs.com/recipes/prisma)にある手順を基本としています。

下記の手順で作成したプロジェクトのリポジトリは[こちら](https://github.com/yamato-1923/prisma-training/tree/main)からご確認ください。

### 初期設定

NestJS の CLI をインストールして、プロジェクトを作成します。

```shell
npm install -g @nestjs/cli
nest new prisma-training
```

作成したプロジェクトのディレクトリで、Prisma をインストールします。

```shell
cd prisma-training
npm install -D prisma
```

Prisma CLI コマンドで Prisma を初期化します。

```shell
npx prisma init
```

上記コマンドを実行すると、`prisma/schema.prisma` ファイルと `.env` ファイルが作成されます。

### DB の準備

次に DB を準備します。  
今回は docker-compose でローカルに PostgreSQL のコンテナを作成します。

以下のように `docker-compose.yml` ファイルを作成します。

```yaml:docker-compose.yml
version: '3.9'

services:
  postgresql:
    image: postgres:latest
    container_name: postgresql
    ports:
      - 5432:5432
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
    volumes:
      - './data/psql:/data'
```

`docker-compose.yml` ファイルがあるディレクトリで下記コマンドを実行してコンテナを起動します。

```shell
docker-compose up
```

### schema.prisma ファイルを書く

続いて、`schema.prisma` ファイルに DB 接続設定とモデル定義を書いていきます。

#### DB 接続設定

今回は PostgreSQL を使用するので以下のように記述します。

```:schema.prisma
datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}
```

#### モデル定義

ここで、2 つのツールを使用します。

まずは VSCode の [Prisma の拡張機能](https://marketplace.visualstudio.com/items?itemName=Prisma.prisma)です。

私は `schema.prisma` ファイルのフォーマットのためにこの機能を使っていますが、他にも機能があるようです。

ファイル保存時に自動的にフォーマットさせるために、`settings.json` ファイルに以下を追記します。（`*.prisma` ファイルのみフォーマットに Prisma の拡張機能を使うという設定です）

```json:settings.json
"[prisma]": {
  "editor.defaultFormatter": "Prisma.prisma"
},
```

次にご紹介するのが、[prisma-case-format](https://github.com/iiian/prisma-case-format) というツールです。  
モデル定義は以下のように記述します。

```:schema.prisma
model users {
  id        Int      @id @default(autoincrement())
  name      String
  created_at DateTime @default(now())
  updated_at DateTime @updatedAt
}
```

Prisma CLI コマンドを実行することで、DB のテーブルと TypeScript の型が作成されるのですが、ここで 1 つ問題があります。

DB のテーブル名は、スネークケースで書くことが多いのに対して、TypeScript では変数名をキャメルケース、型名をパスカルケースで書くことが多いです。（[参照](https://typescript-jp.gitbook.io/deep-dive/styleguide#to)）

上記のモデル定義だとスネークケースで TypeScript の型が作成されてしまいます。

ここで役に立つのが prisma-case-format です。まず、prisma-case-format をインストールします。

```shell
npm install -D prisma-case-format
```

次に以下のコマンドを実行します。

```shell
npx prisma-case-format --file prisma/schema.prisma
```

すると、モデル定義が以下のように自動変換されます。

```:schema.prisma
model Users {
  id        Int      @id @default(autoincrement())
  name      String
  createdAt DateTime @default(now()) @map("created_at")
  updatedAt DateTime @updatedAt @map("updated_at")

  @@map("users")
}
```

`@map` は DB のテーブルで別名を定義できるデコレーションです。これによって DB ではスネークケース、TypeScript ではキャメルケースにできます。

これで `schema.prisma` ファイルを作成できました。

### DB に反映させる

最後に DB への反映です。

起動したコンテナと接続するための URL を `.env` ファイルに記述します。

```:.env
DATABASE_URL="postgresql://user:password@localhost:5432/mydb?schema=public"
```

以下のコマンドを実行して DB のテーブルと TypeScript の型を作成します。

```shell
npx prisma migrate dev --name init
```

以上で本記事の対象としている手順は終了です。TypeScript のアプリケーションの実装については他のドキュメントを参照してください。

## 参考

- https://qiita.com/ebatan-developer/items/14031910f869b78b1439
- https://qiita.com/ebatan-developer/items/14031910f869b78b1439
- https://zenn.dev/tossy_yukky/articles/0075f9f0054b39d4ef59
- https://kimizuy.dev/blog/post/format-schema-prisma

## 余談

テーブル名は複数形、TypeScript の型名は単数形にすることがありますが、prisma-case-format のオプションを使うことでそれにも対応できるようです。  
このような便利なツールを作ってくれる人には頭が上がりません。