2023年2月21日 • ☕️ 3 min read

Prismaは?

非常に有名なORMツールとなります。特にRDBとの相性が抜群で、とても使いやすいです。

個人的にPrismaの利点と言われると。

データモデルを簡単に定義できる。SQLを書かずに簡単にDBの操作できる。また、型安全

データモデルをPrisma schemaで定義するだけで、データベースのテーブル、インデックスなどを自動的に作成できます。また、DBとやりとりをするための関数(Prisma Client)もschemaを基にして自動生成してくれます。

さらに、PostgreSQL、MySQL、SQL Serverをサポートしており、移行も簡単です。また、SQLiteも使えるので、一般開発者にも優しいです。

マイグレーションのサポート。Prisma Migrateは実に便利

SQLのDDLを考える必要がなく、データベースのスキーマを変更するだけでPrismaが変更を追跡し、自動生成してくれます。また、手動で変更することも可能。

既存のDBへの導入はPrisma Introspectionのおかげでめちゃくちゃ簡単

既存の複雑なDBへPrismaを導入するのにハードルを感じる方がいるかもしれません。しかし、Prisma Introspectionを使えば簡単です。schema.prismaにproviderとDB URLを設定し、prisma db pullを実行するだけで、schemaを全部生成してくれます。もちろん、DBを操作するための関数も自動生成されます。ブラボー。

PrismaとMongoDB

今参画しているプロジェクトでは、1年半前からMongoDBを使用しています。当時技術選定する際、残念ながらPrismaはbeta版だったため、MongoDBのサポートを断念しました。去年5月ごろようやく正式にリリースされましたが、最近もう一度PrismaとMongoDBの相性を確認しようと思っています。

Prisma+MongoDBのQAスレッド: https://github.com/prisma/prisma/issues/1277#issuecomment-1130038997

メリットは**Prismaとは?**に書いたとおりですが、問題点もあります。

Prisma Migrateを使えない

prisma_migrate.png

現時点では、PrismaはMongoDBをサポートしていませんし、将来的にサポートする予定もないようです。ただし、既存のMongoDBコレクションに対しては、prisma db pullを使用することでスキーマを自動生成できます。また、prisma db pushを使用することで、スキーマの変更を反映できます(ただし、これはマイグレーションをサポートするわけではありません)。スキーマに変更がある場合、—force-resetオプションを追加する必要がありますが、これにより既存のデータが失われることになります。

MongoDB 4.2以降が必要。また、トランザクションを使ってデータを更新するため、replica setの有効も必要

prisma_prerequisites.png

AWSのDocumentDBを使う場合、MongoDB4.0との互換性をある程度保証しているが、「PrismaとMongoDB4.2+」の組み合わせ条件に達していないようです。

https://docs.aws.amazon.com/documentdb/latest/developerguide/mongo-apis.html

Prismaのcommunityにうまくレコードを作れない報告もあります。

https://github.com/prisma/prisma/issues/13205#issuecomment-1120092087

なので、AWSにインフラを構築する予定があれば、十分な検証が必要です。

MongoDBの複雑なnested objectをうまくサポートしていない

MongoDBの動的なnested objectを使いたいため、MongoDBを選定した人が少なくないでしょう。Prismaなら2つの方法で複雑なobjectを操作できます。

  1. すべての型を丁寧に定義する。ただし、そうすると、MongoDBの柔軟性を失うため、本末転倒の気がします。RDBへ切り替えた方がマシかもです。
Copy
type InnerLayer1 {
  body        String
  header      String
}

type InnerLayer2 {
  id              String?
  innerLayer1     InnerLayer1?
}

type InnerLayer3 {
  id              String?
  innerLayer2     InnerLayer2?
}

model User {
  id         String      @id @default(auto()) @map("_id") @db.ObjectId
  nestedObj    InnerLayer3
}
  1. JSON型を使う。それも問題があり、取り出す時と保存する時一々JSON変換処理を行わなければいけません。
Copy
model User {
  id         String      @id @default(auto()) @map("_id") @db.ObjectId
  nestedObj  JSON
}

大したもんじゃないかもしれないが、PrismaがMongoDBのtext search(全文検索)をまだサポートしていない

ちなみに、PostgreSQLとMySQLのfull-text searchもbeta版です。

https://www.prisma.io/docs/concepts/components/prisma-client/full-text-search

Prismaは元々RDB向けのツールなので、複雑な、階層の深いMongoDBのcollectionを更新する時、パフォーマンスが良くない可能性も考えられる

大規模なシステムを構築する時、慎重に検証した方がいいと思います。

完了

個人的にPrismaが大好きだけど、残念ながら、MongoDBとの相性はまだ良いとは言えません。今後Prismaの進化へ期待します。Prismaが好きな方、ぜひ star をつけてあげましょう。


ThunderMiracle

Blog part of ThunderMiracle.com