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
1.9k
Prismaでスキーマ変更を行う際のベストプラクティス
ryusaka
May 11, 2024
Tweet
Share
Featured
See All Featured
The Cost Of JavaScript in 2023
addyosmani
27
4.2k
Side Projects
sachag
451
41k
Building an army of robots
kneath
300
42k
The Pragmatic Product Professional
lauravandoore
28
6k
Design by the Numbers
sachag
277
18k
YesSQL, Process and Tooling at Scale
rocio
165
14k
The Power of CSS Pseudo Elements
geoffreycrofte
63
5.1k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
9
330
A better future with KSS
kneath
231
17k
Optimizing for Happiness
mojombo
372
69k
Speed Design
sergeychernyshev
7
190
Building Effective Engineering Teams - LeadDev
addyosmani
42
2.1k
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!