Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Prismaでスキーマ変更を行う際のベストプラクティス
Search
ryusaka
May 11, 2024
6
2.3k
Prismaでスキーマ変更を行う際のベストプラクティス
ryusaka
May 11, 2024
Tweet
Share
Featured
See All Featured
Producing Creativity
orderedlist
PRO
341
39k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
41
2.1k
Fireside Chat
paigeccino
32
3k
Java REST API Framework Comparison - PWX 2021
mraible
PRO
28
7.9k
Building an army of robots
kneath
302
42k
A designer walks into a library…
pauljervisheath
202
24k
Six Lessons from altMBA
skipperchong
26
3.5k
For a Future-Friendly Web
brad_frost
175
9.4k
Side Projects
sachag
452
42k
Git: the NoSQL Database
bkeepers
PRO
425
64k
The Language of Interfaces
destraynor
154
24k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
27
790
Transcript
Prismaでスキーマ変更を行う際のベストプラクティス 坂本竜 / ryusaka TSKaigi 2024 in 中野
ryusaka / 坂本 竜 株式会社 ミツモア / MeetsMore inc. プロワンリードエンジニア
2017年 創業2ヶ月後に最初のメンバー(インターン)に →そのまま新卒第一号で入社 TypeScriptダイダイダイスキ ヤクルトファン @ryusaka 自己紹介 About me
プロワンの構成 Prisma Nest.js TypeScript Next.js ←今回の主役 with
Prismaは... • TypeScript ORM • 裏にある各種データベースを意識せずに開発可能 • スキーマ定義から型を自動生成し、Type-Safeな開発が可能 • マイグレーションは自動生成、適用も”割と”簡単
◦ ↑これを定常的に実施する上で気をつける点について話します Prismaの特徴
ミツモアでは、AWS ECSを利用してBlue/Greenデプロイを実施している(DBは一つ) • DB Migration → APIサーバー → Webサーバーの順でデプロイ •
24/365で動いている & 2週間に1度程度リリースがあるのでメンテナンス停止はなし デプロイ順 Bakground DB Before Migration API Old API New Web Old Web New DB After Migration API Old Web Old DB After Migration Web Old API New DB After Migration 1 2 3 4
突然ですが... memo に消えてもらいます APIのmemoの読み書きに関する処理も削除 マイグレーション Migration ↓ model chat {
id @id text String memo String } model chat { id @id text String }
1. 初期状態 Initial State デプロイ前はDB、API双方にmemoがいます • DBにはmemoがいる • APIで利用している Prisma
Client からも消えていない
2. DBマイグレーション後 After DB Migration DBからmemoが消えました • 古いAPIで利用している Prisma クライ
アントからは消えていない ここでアクセスが来るとDBにはカラムが もう無いのでエラーになる • Prismaの生成するSQLには明示的に memoが含まれてしまう await prisma.chat.findFirst() SELECT "t1"."id", "t1"."text", "t1"."memo" FROM "public"."chat" AS "t1" ↓ 生成されるSQL
3. APIサーバーリリース後 After API release APIからもmemoが消えました • Prismaからも消える • この状態になればエラーは発生しない
• DBのマイグレーションとAPIサーバーのリリースタイミングには必ずラグがある ◦ = 2を飛ばして1→3にはできない
答え: リリースを最低2回に分ける 1. Prismaから削除する 2. DBから削除する (FEでも利用していたらその修正も含めると最低3回にする必要がある) ※そもそもPrismaじゃなくても同じだろっていう話なのですが、Prismaにデータベー スが隠されているので遭遇するまで案外気がつきませんでした ではどうすればいいのか?
マイグレーションは自動生成なのに どうやってリリースを分けるの?
Prisma上だけ消えてもらえます! そう、Prismaならね。 @ignore を付与することで、ALTER TABLEはせず、Prisma Client からのみ消 す • Prismaの発行するSQLからも消える
• コード内で利用していると型エラーに なるので修正箇所は特定が容易 正しいマイグレーション ↓ model chat { memo String } model chat { memo String @ignore } model chat { } 1回目のリリース 2回目のリリース(ここでALTER TABLE) await prisma.chat.findFirst({ // ↓エラー select: { memo: true } }) ↓
DBからいきなりカラムを消してはいけない • Blue/Greenデプロイしているとエラーが起きてしまう • よく考えると当然ですが、案外いきなり削除をやってしまいそうになる Prismaを使ってDBからカラムを消すときは @ignore を使おう • 2回以上に分けてリリースすることで問題を回避
• 公式ドキュメントは教えてくれない ◦ これくらいしか記述がない→ 他にも話したいことは色々... • Nest.jsとの組み合わせ • Kyselyとの共存 • JOINが使えるようになった(え、使えなかったの??と思った人いますよね) まとめ
Thank you!