matobaの備忘録

和歌山と東京を往復しつつ活動するエンジニアの記録

TypeScriptのORM、Prismaを調べたメモ

色々あって、TypeScriptのORM、Prismaについて調べておきたい機運が高まってきたので調べておきました。 ここではざっと調べたメモを残しておきます。

なお、私は、Prismaでの開発経験はなく、ざっくりドキュメントやブログを見て集めた情報で手を動かしていません。(手はこれから動かしていく&間違いに気づいたら加筆します)

なので、勘違いが含まれている可能性があるため、正確な情報は各自で確かめるようお願いします。また、間違いに気づいた人は指摘いただけるとありがたいです。

概要

できること(≒できそうなこと)

  • Prisma Schemaという独自言語でデータモデルを定義できる
    • 物理的なテーブルを定義するのではなく、あくまでクライアントの視点でデータモデルを宣言的に定義する。
  • Prisma Schemaを元にDBのテーブルを作成できる。
    • これはPrisma Migrateと呼ばれる。実行時にSQL(DDL)を生成し、マイグレーション履歴が生成される。
    • 既存データを維持した上で、マイグレーションできる。
  • Prisma ClientでDBアクセスができる
    • いわゆるORMのようなもの。マイグレーション履歴を考慮しつつClientが生成される。
    • 実行時にSQL(DML)を生成する。
  • 既存のDBを解析して、Prisma Schemaを生成できる。
    • Prisma Instrospectionと呼ばれる。
  • Prisma Studio と呼ばれる管理インタフェースがある。
    • ブラウザで動くやつ。
    • Prisma のデータモデルに対してデータを操作、閲覧できる。
  • Prisma Schemeで書いたデータモデルを型定義として利用できる。
    • Next.jsやGraphQL、NestJSなどで利用できるらしい。

注意点(Prismaの新しいところ)

  • Prismaは従来のORMとは違う考え方で作られている。 Prisma公式: Is Prisma an ORM?
    • いわゆる、Active Record パターンでも、Data Mapperパターンでもない。
    • Prismaは、スキーマに従った問い合わせに基づいてデータベース問い合わせを行ない、結果をオブジェクトで返す。
  • Prisma Schemaのモデルは、Active Recordでのモデルと違う
    • Active Recordは、テーブルを宣言的にモデルで定義する。テーブル間のリレーションは、宣言時に指定する。
    • Prisma Schemaでは、呼び出す側から見たモデルを宣言する。テーブル間のリレーションは、Prisma側がよしなに生成する。
    • つまり、 Prismaを使う場合、Data MapperをPrismaに丸投げできる。 Prismaはスキーマの変更履歴を管理し、適切にData Mapperを生成する。

Prismaと従来のData Mapperを比較した表がPrisma公式にて紹介されているので、こちらをみるのがわかりやすい。

f:id:mtb_beta:20211226091544p:plain
参照URL: Is Prisma an ORM? | What is an ORM? | Prisma Docs

できないこと(≒難しそうなこと)

  • 複雑なデータマイグレーションが難しそう
    • 公式ドキュメントを見ても複雑なデータマイグレーションについては記載がない。
    • 簡単なマイグレーションについては公式で例がある
    • 実際に使ってみると、難しいケースに遭遇しないのかもしれない。(わからない)
  • 細かいクエリの制御ができないかも
    • 「Prismaは、データを抽象化して制御量を減らし、生産性を上げる仕組みなので、細かく制御したいなら、 Prisma以外を使う方が良いケースがある」との話が公式にある。

所感

  • 凄そう(小並感)
  • とりあえず「全部をTypeScriptでやってしまいたい」という流れにある ORMだと思った。
  • 「Schemaを宣言的に定義できるようにしつつ、マイグレーションも管理する。そしてマイグレーション履歴からData Mapperを自動生成する」という仕組みだという印象で、実際に物理的なテーブルを意識することはなくなるように見えた。
  • Data Mapperを自動生成したり物理的なテーブル構造を意識しないようにすることで、SQL自体は重くなる可能性が高まると思うので、「開発スピードを上げて、劣化したパフォーマンスはとりあえずお金で解決する」という考えがベースにあるように感じた。
  • 実際の開発に使ったことがないので、どれだけ便利か、はまだよくわからない。

参考にした記事