4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

PlanetScaleからSupabaseに移行する(Prisma)

Last updated at Posted at 2024-03-11

PlanetScaleは、2024年4月8日に無料枠を廃止します。

そのため、私はとあるWebサービスのDBをPlanetScaleからSupabaseに移行することにしました。

Supabaseは、無料で利用することもできるPostgreSQLベースのDBです。

Supabaseは既に利用したことがあり、今回選定しました。大変使いやすく、またphpMyAdminのようにWeb上でデータを直接編集できるところも便利でおすすめです。

移行手順

今回は少量のデータだったため試していませんが、大量のデータがある場合はpgloaderを使うほうが良いかもしれません。

前提として、今回移行するサービスは、以下の記事に書かれたような構成で作られています。

DBとしてPlanetScaleを利用し、ORMとしてPrismaを利用しています。

Supabaseのテーブル作成

SupabaseとPrismaを接続します。Prismaでスキーマが定義されているため、接続するだけで自動的にDBの準備は完了します。

SupabaseでPrismaを使う方法は、下記の公式ドキュメントに詳しく書かれています。

重要な部分は、.envでDATABASE_URLの他にDIRECT_URLが必要になる点、そしてDATABASE_URLの末尾には?pgbouncer=trueが必要な点です。

Supabaseは、PostgreSQLの接続にあたりコネクションプーリング機能を利用しています。これは、接続や切断を繰り返した際にメモリが枯渇したり性能が劣化したりするのを防ぐ機能です。

Supabaseではこの機能のために、Session modeとTransaction modeという2種類の接続先が用意されており、操作の性質によって接続先を変えることでパフォーマンスが最大化できるようになっています。

モード毎の接続先は、Supabaseの「Project Settings」ページから「Database Settings」を開き、ページ最上部の「Connection string」という項目でそれぞれ確認できます。

.envのDATABASE_URLにはTransaction modeの接続先を、DIRECT_URLにはSession modeの接続先を指定してください。指定の際に、DATABASE_URLの末尾に?pgbouncer=trueを追加するのを忘れないようにしてください。

URLは、パスワードの部分のみ[YOUR-PASSWORD]となっていますので作成時に指定したDBのパスワードで置き換えてください。

続いて、schema.prismaを以下のように置き換えてください。

schema.prisma
datasource db {
-  provider     = "mysql"
-  url          = env("DATABASE_URL")
-  relationMode = "prisma"
+  provider  = "postgresql"
+  url       = env("DATABASE_URL")
+  directUrl = env("DIRECT_URL")
}

ここまでできたら、ターミナルでprisma db pushすればDBテーブルが作成できるはずです。

PlanetScaleのデータをエクスポート

GUIからエクスポートすることは現状できないので、PlanetScale公式のCLIであるpscaleを利用します。

ターミナルでpscale auth loginしてからpscale database dump [database] [branch]します。branch名はだいたいmainだと思います。

すると、カレントディレクトリにpscale_dump_*で始まるディレクトリが作成され、その中にsql形式のファイルが出力されます。

*-schema.sqlみたいなファイルにスキーマが定義されており、*.00001.sqlみたいなファイルにデータが定義されています。前者は使わないです。

Supabaseにデータをインポート

いかにもそのままインポートに使えそうなSQLが生成されましたが、MySQLとPostgreSQLでクォーテーションの扱いが異なるため、そのままでは使えません。

「"」を「'」に、「`」を「"」に、「\'」を「''」に変換する必要があります。

簡単なやり方として、VSCodeの検索機能でファイルを絞り込んで置換する方法があります。

image.png

「含めるファイル」に*00001.sqlを指定し、すべて置換を実行すると置き換えることができます。

この方法では、元の文字列にダブルクォーテーションが含まれている場合などに、データが破損する可能性があります。データの性質に合わせて、適宜やり方を変更してください。

置き換えることができたら、SupabaseのSQL EditorにSQLを貼り付けて実行していきましょう。

なお、よく出るエラーとして、外部キー制約によるエラー、真偽値が数値で書かれていることによるエラーがあります。

外部キー制約によるエラー

ERROR: 23503: insert or update on table "*" violates foreign key constraint "*"

一時的に無効化できるようです。

真偽値が数値で書かれていることによるエラー

ERROR: 42804: column "*" is of type boolean but expression is of type integer

こちらは例えば「0」を「'0'」に置き換えることで、PostgreSQLに真偽値だと解釈させることができます。

まあ大体「Debug with Supabase AI」でなんとかなります。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?