Prismaのschema.prismaにて、フィールドを更新するときはマイグレーションファイルを作成しよう

この記事は、僕がいつも`schema.prisma`を更新するときにエラーを出してしまうので、忘備録としてマイグレーションの手順を残しておきます。

`schema.prisma`にて定義され値得るモデルに新しいフィールドを追加する場合を考えましょう。

例えば、次のように`User`モデルに`nickname`フィールドを追加したいとします。

```prisma
model User {
  id    String @id @default(cuid())
  email String @unique
  name  String @default("")

  nickname String? @default("") // 新しく追加したいフィールド
}
```

環境変数`DATABASE_URL`は、ローカル環境のものに設定されていることを確認します。

```env
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/postgres?connection_limit=40"
```

この状態で`npm run setup`を実行すると、エラーが発生してしまいます。

> `npm run setup`は`prisma generate && prisma migrate deploy && prisma db seed`を実行しています。これは、Remix Blues Stackのプロジェクトを作成したときに自動的に用意されるスクリプトです。


```shell
Running seed command `ts-node --require tsconfig-paths/register prisma/seed.ts` ...
PrismaClientKnownRequestError: 
Invalid `prisma.user.create()` invocation in
/workspaces/remix-app/prisma/seed.ts:17:34

  14 const hashedPassword = await bcrypt.hash("racheliscool", 10);
  15 
  16 // create an admin user
→ 17 const user = await prisma.user.create(
The column `nickname` does not exist in the current database.
    at RequestHandler.handleRequestError (/workspaces/remix-app/node_modules/@prisma/client/runtime/index.js:34310:13)
    at RequestHandler.request (/workspaces/remix-app/node_modules/@prisma/client/runtime/index.js:34293:12)
    at async PrismaClient._request (/workspaces/remix-app/node_modules/@prisma/client/runtime/index.js:35273:16)
    at async seed (/workspaces/remix-app/prisma/seed.ts:17:16) {
  code: 'P2022',
  clientVersion: '4.6.1',
  meta: { column: 'nickname' }
}

An error occurred while running the seed command:
Error: Command failed with exit code 1: ts-node --require tsconfig-paths/register prisma/seed.ts
```

Prismaのエラーメッセージを見ると、`nickname`フィールドが存在しないということがわかります。

Prismaに熟練している開発者の方なら何が問題かもうすでにお気づきかと思います。そうです。マイグレーションファイルが作成されていないのです。

最初にマイグレーションファイルを作成しましょう。

```shell
node ➜ /workspaces/remix-app (main) $ npx prisma migrate dev --name "add-nickname"
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Datasource "db": PostgreSQL database "postgres", schema "public" at "localhost:5432"
...
The following migration(s) have been created and applied from new schema changes:

migrations/
  └─ 20230225141819_add_nickname/
    └─ migration.sql

Your database is now in sync with your schema.

✔ Generated Prisma Client (4.6.1 | library) to ./node_modules/@prisma/client in 157ms
```

マイグレーションファイルが作成されたことが確認できたら、`npm run setup`を実行します。

```shell
node ➜ /workspaces/remix-app (main) $ npm run setup

> setup
> prisma generate && prisma migrate deploy && prisma db seed

Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma

✔ Generated Prisma Client (4.6.1 | library) to ./node_modules/@prisma/client in 82ms
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()
```

warn Versions of prisma@4.10.1 and @prisma/client@4.6.1 don't match.
This might lead to unexpected behavior.
Please make sure they have the same version.
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Datasource "db": PostgreSQL database "postgres", schema "public" at "localhost:5432"

7 migrations found in prisma/migrations


No pending migrations to apply.
Environment variables loaded from .env
Running seed command `ts-node --require tsconfig-paths/register prisma/seed.ts` ...
Database has been seeded. 🌱

🌱  The seed command has been executed.
```

これで完了です。