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.5k
Prismaでスキーマ変更を行う際のベストプラクティス
ryusaka
May 11, 2024
Tweet
Share
Featured
See All Featured
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
120k
How STYLIGHT went responsive
nonsquared
98
5.4k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
4
350
The MySQL Ecosystem @ GitHub 2015
samlambert
250
12k
Raft: Consensus for Rubyists
vanstee
137
6.8k
Facilitating Awesome Meetings
lara
52
6.2k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
330
21k
Statistics for Hackers
jakevdp
797
220k
Fantastic passwords and where to find them - at NoRuKo
philnash
51
3k
Become a Pro
speakerdeck
PRO
26
5.1k
Building a Scalable Design System with Sketch
lauravandoore
461
33k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.3k
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!