TypeScript の SQLite 用 ORM を探し続けている

aliyome
·

TypeORM, Prisma, drizzle-orm などを試しては全部しっくり来ないなぁ、というのを年に数回繰り返している。

TypeORM

実務で1年くらいくらい使った。最近の案件でもまた使うことになった。

型がふわふわしていて全く安心できない。migration や seeding の仕組み(プラグイン)も好みではない。仕方なく業務では使うけど新規案件の技術選定では絶対に選択肢から外す、という強い意志を持っている。

Prisma

良い

が、SQLite3のサポートがかなり厳しい。

例えば STRICT なテーブルを作ろうとすると prisma migrate や prisma db pull で余計な差分が生まれたり、そもそもうまくいかなかったりする。

他にも SQLite3 には DATETIME 型は存在しないんだが Prisma は DATETIME 型の DDL を生成する。

日付周りは怪しい部分が多い。DATETIME 型のカラムに @default(now()) を指定すると、そのカラムの DEFAULT VALUE に CURRENT_TIMESTAMP が設定される。が、実際に Prisma を使ってデータを登録すると JS の Date.now() の値が登録される。**必ず**Prisma 経由でデータの入出力を行うなら問題ないが、 DB に直接値を INSERT すると CURRENT_TIMESTAMP なので当然 "2024-04-13 11:22:33" みたいな文字列が登録される。かなり厳しい

トランザクションのネストができない。

スキーマ定義で @dbgenerated を指定すると prisma migration dev 時に毎回差分が出て使い物にならない

など、色々と言いたいことはある。が、それでも TypeORM よりは Prisma を選択したい。

Drizzle ORM

良い

と思っていた

ドキュメントを精査すると Prisma よりも好みの API で、さらに前述の Prisma で SQLite3 を利用する際のつらみがほとんど無い。

これは良い、と思って Drizzle ORM で Web サービスを一つ作ってみたが、なんというか Prisma の方がはるかに書き味が良い、という感覚がある。

Drizzle は薄い ORM で SQL 直接書いているような書き味があり、それが非常に好ましいと思っていたのだが、実際にアプリケーション開発をしてみると Prisma の簡潔さが恋しい、という感情に支配された。

あとはネストしたプロパティを findMany で指定できないので select from join で自分で結合する必要があるのが面倒

[Allow referencing deeply nested properties in relational queries · Issue #696 · drizzle-team/drizzle-orm · GitHub](https://github.com/drizzle-team/drizzle-orm/issues/696)

何よりスキーマ定義が Prisma と比べて圧倒的に面倒くさい。Prisma は専用の DSL でスキーマを定義するが、Drizzle は愚直に TypeScript で実装する。Prisma は DSL の書き味がとても良く、さらに VSCode の拡張を入れるとリレーションもサクサク書けて体験が本当に良い。

Drizzle はとても良い ORM だと今でも思っているが、第一選択肢としては Prisma を選びたい、と思っている