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
5 minutes of I Can Smell Your CMS
philhawksworth
202
19k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
329
21k
Typedesign – Prime Four
hannesfritz
40
2.4k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
226
22k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.1k
Unsuck your backbone
ammeep
668
57k
Done Done
chrislema
181
16k
Rails Girls Zürich Keynote
gr2m
94
13k
Designing the Hi-DPI Web
ddemaree
280
34k
Automating Front-end Workflow
addyosmani
1366
200k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
48k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
0
100
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!