🚧

Prisma+PostgreSQL構成からのSupabase移行で遭遇したエラーと解決策

に公開

概要

今回の場合はPrismaで既に schema.prisma が定義されていて、既にPostgreSQLを使っているところを、SupabaseのPostgreSQLを使うように設定した際に出たエラーを解消した際の記事になります。

Version

※ 以下のVersionでしか試してないので、他のVersionだと挙動が異なる可能性があります。

$ npx prisma --version
prisma                  : 6.8.2
@prisma/client          : 6.8.2

ローカルでのmigrate失敗編

Supabase CLIでローカルにコンテナを起動し DATABASE_URL にそちらを向くようにして prisma migrate dev を実施した際のエラー対応になります。

エラーの詳細

Drift detected: Your database schema is not in sync with your migration history.

The following is a summary of the differences between the expected database schema given your migrations files, and the actual schema of the database.

It should be understood as the set of changes to get from the expected schema to the actual schema.

[+] Added extensions
  - pg_graphql

[+] Added extensions
  - pg_net

[+] Added extensions
  - pg_stat_statements

[+] Added extensions
  - pgcrypto

[+] Added extensions
  - pgjwt

[+] Added extensions
  - supabase_vault

[+] Added extensions
  - uuid-ossp

- The migrations recorded in the database diverge from the local migrations directory.

こちらはSupabaseが自動で設定しているPostgreSQLの拡張がこれからmigrateする内容に入ってない為に怒られている様です。

以下のIssueを参考に対応しました 👇

https://github.com/prisma/prisma/issues/19100

※ SupabaseのPostgreSQLにどんな extensions が設定されているかは以下のSQLで一覧表示できます。

SELECT
  ext.extname AS extension_name,
  ext.extversion AS extension_version,
  ext.extrelocatable AS extension_relocatable,
  pn.nspname AS extension_schema
FROM pg_extension ext
INNER JOIN pg_namespace pn ON ext.extnamespace = pn.oid
ORDER BY ext.extname ASC

最終的な解決策

以下の仕組みを使って 1つまたは複数の移行がすでに適用されていると仮定するように指示する という事を行い、上記で怒られていた Added extensions が既に適用されているという状態にして、通常のmigrationを実施します。

https://www.prisma.io/docs/orm/prisma-migrate/workflows/baselining

  • mkdir -p prisma/migrations/0_init0_init ディレクトリ作成

  • 以下内容の migration.sql ファイルを作成 (※1)

    -- CreateSchema
    CREATE SCHEMA IF NOT EXISTS "extensions";
    
    -- CreateSchema
    CREATE SCHEMA IF NOT EXISTS "graphql";
    
    -- CreateSchema
    CREATE SCHEMA IF NOT EXISTS "public";
    
    -- CreateSchema
    CREATE SCHEMA IF NOT EXISTS "vault";
    
    -- CreateExtension
    CREATE EXTENSION IF NOT EXISTS "pg_graphql" WITH SCHEMA "graphql";
    
    -- CreateExtension
    CREATE EXTENSION IF NOT EXISTS "pg_net" WITH SCHEMA "extensions";
    
    -- CreateExtension
    CREATE EXTENSION IF NOT EXISTS "pg_stat_statements" WITH SCHEMA "extensions";
    
    -- CreateExtension
    CREATE EXTENSION IF NOT EXISTS "pgcrypto" WITH SCHEMA "extensions";
    
    -- CreateExtension
    CREATE EXTENSION IF NOT EXISTS "pgjwt" WITH SCHEMA "extensions";
    
    -- CreateExtension
    CREATE EXTENSION IF NOT EXISTS "supabase_vault" WITH SCHEMA "vault";
    
    -- CreateExtension
    CREATE EXTENSION IF NOT EXISTS "uuid-ossp" WITH SCHEMA "extensions";
    
  • 次のコマンドを実施し 0_init は解決済みとして _prisma_migrations にマークする

    npx prisma migrate resolve --applied 0_init
    
  • あとは普通に prisma migrate dev などを実施


※1 ファイル作成までの作業履歴

以下の schema.prisma を作成

generator client {
  provider        = "prisma-client-js"
  previewFeatures = ["multiSchema", "postgresqlExtensions"]
}

datasource db {
  provider   = "postgresql"
  url        = env("DATABASE_URL")
  extensions = [pg_graphql(schema: "graphql"), pg_net(schema: "extensions"), pg_stat_statements(schema: "extensions"), pgcrypto(schema: "extensions"), pgjwt(schema: "extensions"), supabase_vault(schema: "vault"), uuid_ossp(map: "uuid-ossp", schema: "extensions")]
  schemas    = ["extensions", "graphql", "public", "vault"]
}

以下コマンドで prisma/migrations/0_init/migration.sql 作成

npx prisma migrate diff \
  --from-empty \
  --to-schema-datamodel prisma/schema.prisma \
  --script > prisma/migrations/0_init/migration.sql 

0_init は解決済みとして _prisma_migrations にマークしてしまうので、schema.prisma は元に戻しときます。


デプロイ編

GoogleCloudのCloudRunへデプロイするアプリで、CloudBuildを使用して prisma migrate を実施しようとすると以下のエラーに遭遇。

Datasource "db": PostgreSQL database "postgres", schema "public" at "aws-xxxxx.pooler.supabase.com:6543"
Error: P1001: Can't reach database server at `aws-xxxxx.pooler.supabase.com:6543`

Supabaseにちゃんと接続できていない様です。

schema.prismaDATABASE_URL にはSupabaseダッシュボードの 「Connect」>「ORMs」の DATABASE_URL を設定しました。

image1.png

以下の記事によると DIRECT_URL の指定が必要との事なので、設定してみる。👆の設定の DIRECT_URLschema.prismaに設定して試してみます。

https://qiita.com/Naoki_ganbarimasu/items/f18eac6e1403bb235ba6

  • DIRECT_URL のドキュメントはこちら👇

https://www.prisma.io/docs/orm/reference/prisma-schema-reference

上記を試してもエラーが解消せず…

色々試行錯誤してやってたんですが、よくCloudBuildの設定を見ると pool にプライベートの接続Poolが設定されていて、これが原因でした 😇

options:
  logging: CLOUD_LOGGING_ONLY
  pool: # ←ここにプライベート接続Poolが設定されていた
    name: xxxxxx

参考URL

https://zenn.dev/probmkr/scraps/1f412ad1a0d278

Discussion