Supabase CLIを使ってリモート（ supabase.com ）のDBマイグレーションを行う

こんにちは。Supabase便利です！

ローカル開発に便利な [Supabase Cli](https://supabase.com/docs/guides/local-development/cli/getting-started) ですが、リモートの操作もできるようです。

あまり情報が出てきませんが、DBマイグレーションを行う方法がありました。
そのまとめです。

## ログイン
コマンドラインで `supabase login` をブラウザでSupabaseの認証画面が開き、確認コードが出てきます。そのコードをターミナルに貼り付けると内部的にSupabaseのトークンが、CLI側にセットされます。
これで `supabase` コマンドでリモート（supabase.com）にアクセスすることができます。


```
supabase login
```

![Screenshot 2025-01-08 at 14.11.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/a73738d4-0527-ca84-cafa-9cd9b59b8039.png)


## リンク
リモートのデータベースを修正する場合、ローカルの環境とリモート（supabase.com）のプロジェクトを「リンク」させておく必要があります。

`supabase link` というコマンドを使うことでローカルの作業ディレクトリとリモートのプロジェクトを紐づける事ができます。
内部的には設定ファイルの `config.toml` にプロジェクトのIDが書き込まれ、以後作業をする際に該当のプロジェクト宛にコマンドを実行してくれます。
プロジェクトIDのオプションを与えないと対話式でどのプロジェクトに紐づけるか、ログイン済みのアカウントで確認できるプロジェクト一覧から聞かれます。

```bash
supabase link



selected project: xxxxxxxxxxxx
Enter your database password (or leave blank to skip):
Connecting to remote database...
Finished supabase link.
WARNING: Local config differs from linked project. Try updating supabase/config.toml
diff supabase/config.toml rxu
--- supabase/config.toml
+++ xxxxxxx
@@ -48,12 +48,11 @@
 enabled = true

.....
```

## local vs linked （「ローカル」と「リンクト」）
主にデータベース関連のコマンドを実行すると、その実行がローカルに向けてか、リンクされたプロジェクトに向けられます。
ローカルに向けるものは local（ローカル）、リンク先のプロジェクトは linked（リンクト）と呼ばれています。


例えば `supabase db pull` コマンドはデフォルトで `linked` 向けに実行されます。それぞれのデフォルトの動作はヘルプを見ると書いてあります。

```
supabase help db pull | grep -e link -e local


      --linked            Pulls from the linked project. (default true)
      --local             Pulls from the local database.
```

## linkedの実行時にパスワードを聞かれる
DB操作をlinkedに向けて行う場合、都度パスワードを聞かれます。
都度都度聞かれるのが面倒な場合、パスワードを保存しておくことができます。

PostgreSQLの場合、 `.pgpass` ファイルか `PGPASSWORD` という環境変数に格納しておくことが多いです。

https://www.postgresql.jp/docs/12/libpq-pgpass.html

https://www.postgresql.jp/document/12/html/libpq-envars.html

これらのファイルを作成、もしくは環境変数を設定したとしても `supabase` コマンドには渡りませんので、 -p もしくは --password で与えてやる必要があります。

具体的には下記の様になります。


### パスワードファイルを使う場合

パスワードファイルを作成しておきます。


```bash
cat > .pgpass

somethingpassword
```

コマンド実行例

```bash
supabase db dump -p $(cat .pgpass)
```

### 環境変数を使う場合
環境変数の設定。`.bashrc` などに指定しておくこともできます。


```bash
export PGPASSWORD=somethingpassword
```




コマンド実行例

```bash
supabase db dump -p $(echo $PGPASSWORD)
```


もちろんですが、管理には十分注意してください。


## よく使う動作

基本的には公式ドキュメントを見るのが一番です。

https://supabase.com/docs/reference/cli/supabase-db-reset


### DBをリセットする

デフォルトはローカル。下記はローカルのDBをリセットします。

```
supabase db reset
```

linkedは `--linked`。リセットされるので実行には注意。

```
supabase db reset --linked
```

### リモートの差分を拾ってくる

pullのデフォルトはlinked

```bash
supabase db pull
```

### ダンプ（バックアップ）
デフォルトはlinked

```bash
supabase db dump
```

標準出力に出てしまうのでファイに書き出す場合。ファイル名は `dump_日時.sql` です。

```bash
supabase db dump -p $(cat .pgpass) > dump_'date +%Y%m%d%H%M%S'.sql
```

上記を圧縮しながら行う例。

```bash
supabase db dump -p $(cat .pgpass) | gzip > dump_'date +%Y%m%d%H%M%S'.sql
```


## プロジェクトやアカウントを切り替えながら行う
ローカルの環境からリンクする先が複数ある場合に、その切替を行いながらマイグレーション等の作業をスムーズに行う方法です。

### 事前準備（パーソナルアクセストークンの取得）
Link先のSaaS上でパーソナルアクセストークンを生成しておきます。

右上の自分のアイコンから「Account Settings」みたいなところから行います。

![Screenshot 2025-05-22 at 14.30.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/018d324e-e09c-4913-87f0-959339e18de3.png)


### リンク先の変更（ブラウザ利用なし）

取得したアクセストークンを環境変数に埋めてlinkできます。DBパスワードも同時に指定できます。

```bash
export SUPABASE_DB_PASSWORD='xxxxxxxxxx'
export SUPABASE_ACCESS_TOKEN='xxxxxxxx';
supabase link --project-ref xxxxxxxxxxxxxxx
```

## 参考情報

https://egghead.io/lessons/supabase-link-local-database-to-remote-and-run-a-migration-with-supabase