🧊

Cloudflare D1 + Drizzle ORMで、JSON型のカラムを使う

いちおうタイトルには含めたけど、Cloudflare成分は薄め。

D1はSQLiteなので、正確にはJSON型というか、TEXT型のカラムでJSONをよしなにしてくれるモードという感じになる。

Drizzleのスキーマ

myData: text("my_data", { mode: "json" })
  .notNull(),

というように。

Drizzle ORM - SQLite https://orm.drizzle.team/docs/column-types/sqlite#text

blob('', { mode: 'json' })とも書けるけど、こっちは非推奨とのこと。

型をつける

myData: text("my_data", { mode: "json" })
  .notNull()
  .$type<{ name: string; age: number }>(),

デフォルト値いれる

やり方が2通りある。

myData: text("my_data", { mode: "json" })
  .notNull()
  .$type<{ name: string; age: number }>()
  .default('{ "name": "-", "age", 0 }'),

いつも通り、default()でSQLのDEFAULTを使うパターン。

ただし文字列で(TEXT型に対する初期値なので)指定する必要があり・・・。

もう1つは、$default()を使うパターン。

myData: text("my_data", { mode: "json" })
  .notNull()
  .$type<{ name: string; age: number }>()
  .$default(() => ({ name: "-", age: 0 })),

こっちだと型は補完されるけど、SQL文には何も出力されない。ORMがINSERTの時によしなにしてくれるだけ。

ちなみにdefault({ name: "-", age: 0 })って書くと、型エラーにならないから書きがちではあるが、DEFAULT [object Object]って出力されちゃう。

読み出し

カラム自体はTEXT型なので、select()でいい感じにクエリが書けるわけではなさそう。(少なくとも現時点では)

sqlヘルパーを使って、自分でjsonをコネるしかない・・・?

Drizzle ORM - Magic sql“ operator https://orm.drizzle.team/docs/sql

Query JSON · Cloudflare D1 docs https://developers.cloudflare.com/d1/reference/query-json/#supported-functions

まあ、JSONをコネコネしたくなったら負けって感じかもしらんけど。