Prisma Getting Startedの記録+α
はじめに
話題の(?)ORM、Prismaをちょっとだけ触ってみたので記録を載せる
- はじめに
- prisma init
- DATABASE_URL with specific schema
- Model設定
- migration
- migration結果観察
- データ操作
- deployに伴うmigrateの反映
- スキーマ指定したうえでHeroku Postgresqlと一緒に使う
prisma init
Postgresqlで作る場合のコマンドは以下。--datasource-provider
オプションにpostgresql
を指定する
$ npx prisma init --datasource-provider postgresql
DATABASE_URL with specific schema
?schema
パラメータつければスキーマ指定して繋がるらしいのでやってみる。localhostで5432ポートで立ち上げてるポスグレのtestスキーマを指定
DATABASE_URL="postgresql://postgres:@localhost:5432/postgres?schema=test"
Model設定
scheme.prisma
の最下部に以下を追記。モデル定義は適当。ただし以下が自動的に満たせるようにしてみたかったのでその実験を含む。
- UUIDを自動採番
- システムカラム(作成日時と更新日時)を自動設定
model Test { id String @id @default(uuid()) name String created_at DateTime @default(now()) updated_at DateTime @default(now()) }
- 参考
migration
以下コマンドで実行。ちょっと時間かかった。事前に prisma-client
を入れてればもう少し速かった?かも。--name
パラメータはよくわからんが必須らしい。できあがるmigrationファイルのファイル名の後方にprefixとしてくっつく。タイムスタンプはこの--name
パラメータの指定とは別に自動でつく。
npx prisma migrate dev --name test-init
migration結果観察
migration実行時点でスキーマが存在しなければ、npx prisma migrate
で一緒にスキーマも作ってくれるみたい。
データ操作
今回つくったTest
テーブルに1件データを挿入する。以下のコードをつくって実行してみる
async function main() { const user = await prisma.test.create({ data: { name: 'test-1', }, }); console.log(user); }
データ入った&見れた。
deployに伴うmigrateの反映
これをstagingやproductionなどの環境に反映する、例えばHerokuのリリースフェーズなどでこのmigrateする場合にはどうすればいいのか?を考える。個々のmigrateの反映は npx prisma migrate dev
でいいが、ローカルでは既にこれを実施済みのはず。つまり「プロジェクト資産内にmigrationファイルはあるがそれの適用状態がローカルとstaging/productionで異なる」という状態が生まれる。で、コマンド探すとどうやらnpx yarn prisma migrate deploy
というのがある。これを使えばよいらしい。例として、HerokuのProcfileでは
release: npx prisma migrate deploy web: yarn start
とかで書けばよい。
ちなみにちょっと前の情報だが、 「Prismaがmigrateするときに一時的なDatabaseを作成するので、その権限がないとmigrateの段階でエラーになる」 っていうのがある。例えばこのStackoverflowとか。しかし2023年3月時点で試した限りでは、このようなエラーは発生しなかったので、知らない間に改善された?のかもしれない。
スキーマ指定したうえでHeroku Postgresqlと一緒に使う
Prismaでスキーマを指定する場合、DATABASE_URLの末尾に"?schema=hogehoge"
のようにパラメータをつけて指定する。つまり"postgres://postgres:@localhost:5432/postgres?schema=hogehoge"
みたいな感じだ。
一方で、Heroku PostgresqlのDATABASE_URLには?schema=hogehoge
の部分が含まれていない。このため、prisma.schema
でurl = env("DATABASE_URL")
のように指定してしまうと、スキーマを指定することができない。固定の文字列書いてもいいが、それだといくらなんでもイケてない。Herokuが管理するDatabaseの接続文字列DATABASE_URL
を基準に、特定のSCHEMA
を対象に付け加えてprismaで扱えないか?
結論から言うと、以下の方法で出来る(できた)。ちょっと手間だが。
prisma.schema
のurlの設定もと記述をenv("DATABASE_URL_WITH_SCHEMA")
にする- アプリのルートに
/.profile.d/
ディレクトリを掘って、ここにDATABASE_URL_WITH_SCHEMA
環境変数を設定するshellスクリプトを用意する - Herokuのアプリに別途
SCHEMA
環境変数を設定する
これでいける。/.profile.d/
配下のスクリプトのサンプルは以下のような感じ
#!/bin/sh echo "`date -u` start configure-database-schema" echo "DATABASE_URL=$DATABASE_URL" export DATABASE_URL_WITH_SCHEMA=${DATABASE_URL}"?schema="${SCHEMA} echo "DATABASE_URL_WITH_SCHEMA=$DATABASE_URL_WITH_SCHEMA" echo "`date -u` e n d configure-database-schema"
Herokuの/.profile.d/
配下のshellスクリプトは、順序的に言えばreleaseフェーズよりも先に動くので、事前にこうやって環境変数を補足してやることで(もともとそういう目的のためにshellを用意できるための仕組みだ)、スキーマを指定したうえでprismaでmigrateができる。
余談だが、最初は別々の環境変数をprisma.schema
上で文字列結合みたいに指示できるのかと思ったんだが(url = env("DATABASE_URL") + "?" + env("SCHEMA")
)、やってみたらわかるがこれは普通にprismaの構文に反していてエラーになる。というかprisma公式docでも、スキーマ指定するなら、Herokuのこの仕組みのように、スキーマ文字列を付け加えたDATABASE_URLに相当する別の環境変数を用意して、それをprisma.schema
で指定しなさいと書いてある。(下記参考)
これに関しては非常に簡素なサンプルアプリのリポを別途用意したので、興味ある方は参考にしてください。
- 参考