前提と注意事項
この記事では以下を前提としています。
- Supabase CLI がインストールされていること
- ローカル環境に Supabase 環境が構築されていること
上記については以下の記事にまとめていますのでよければ参考にしてください。
⚙️ Supabase CLIとSupabaseのローカル開発環境をセットアップする
Supabase CLIをmacOSで使えるようにし、Supabaseをローカル環境に構築するまでの手順を解説します。
ritaiz.com
この記事のゴール
Supabase CLI を使ってローカル環境の Supabase のデータベースにテーブルを作成したり、データを投入したりします。
また、その後本番環境(リモート)の Supabase(supabase.com
)にローカル環境の内容をプッシュして反映するまでの手順を解説します。
以降では、本番環境のことをローカルに対してリモートと表記します。
テーブルを作成する
テーブルを作成したり変更したりするには、まず作成(もしくは変更)するテーブルについて記述したマイグレーションファイルを作成し、それを元にしたマイグレーションを実行するという流れになります。
Supabase CLI では、以下のようにmigration new
を使って新しくマイグレーションファイルを作成できます。
なお、以降では、Supabase を使用するプロジェクトのルートディレクトリを./my-project
としています。
$ supabase migration new create_users_table
以下が実行結果です。
$ supabase migration new create_users_table
Created new migration at supabase/migrations/20231104222217_create_users_table.sql
./my-project/supabase/migrations
の中にタイムスタンプ付きのマイグレーションファイルが作成されます。
このマイグレーションファイルは、作成時点では空になっています。
ここにどのようなテーブルを作成するかを SQL 文で記述します。
例えば、以下のような内容にします。
create table
public.users (
id not null default uuid_generate_v4(),
nickname text not null default ''::text,
first_name text not null default ''::text,
last_name text not null default ''::text,
first_name_kana text default ''::text,
last_name_kana text default ''::text,
email text not null default ''::text,
created_at timestamp with time zone not null default now(),
updated_at timestamp with time zone not null default now()
);
上記のマイグレーションファイルを作成したら、以下のコマンドでマイグレーションを実行します。
$ supabase db reset
以下が実行結果です。
$ supabase db reset
Resetting local database...
Recreating database...
Setting up initial schema...
Applying migration 20231104222217_create_users_table.sql...
Seeding data supabase/seed.sql...
Restarting containers...
Finished supabase db reset on branch update/update-migration.
ここでローカルの Supabase のダッシュボード(http://127.0.0.1:54323
)にブラウザでアクセスし、テーブル一覧を確認してみると、以下のようにusers
テーブルが作成されていることを確認できます。
これでマイグレーションファイルを作成し、マイグレーションを実行することでテーブルをローカル環境の Supabase に作成することができました。
なお、supabase db reset
は、全てのテーブルを一旦削除した上ですべてのマイグレーションファイルを実行します。
すなわち、データベース自体を削除して再構築するコマンドになります。そのため、もし開発中のアプリを通して投入したデータも削除されてしまいます。
もし新しく作成したマイグレーションファイルだけを実行したい場合は、以下のようにsupabase migration up
を使用します。
$ supabase migration up
以下が実行結果です。
✗ supabase migration up
Connecting to local database...
Applying migration 20231105002001_create_new_table.sql...
Local database is up to date.
supabase db reset
とは異なり、最後のマイグレーション実行以降に新しく作成されたマイグレーションファイルだけを実行します。
本記事執筆時点だと、確認した限りはローカル環境のマイグレーションを戻すコマンドは存在しないようです。
(リモートのマイグレーションを戻すコマンドとしてはsupabase migration repair
を使って可能です。)
テーブルを変更する
今度はテーブルに新しくカラムを追加してみます。
例えば、住所用のカラムとしてaddress
カラムを追加してみます。
作成した場合と同様に、まずはマイグレーションファイルを作成します。
$ supabase migration new add_address_to_users_table
マイグレーションファイルの中身を以下のようにします。
alter table
if exists public.users add address text;
再度マイグレーションを実行します。
$ supabase db reset
以下が実行結果です。
$ supabase db reset
Resetting local database...
Recreating database...
Setting up initial schema...
Applying migration 20231104222217_create_users_table.sql...
Applying migration 20231105033533_add_address_to_users_table.sql...
Seeding data supabase/seed.sql...
Restarting containers...
Finished supabase db reset on branch update/update-migration.
ブラウザでローカルの Supabase のダッシュボードにアクセスしてみると、users
テーブルにaddress
カラムが追加されていることを確認できるはずです。
テストデータを投入する
supabase db reset
では全てのテーブルを削除してしまうので、開発中のアプリケーションを通して投入したデータも消えてしまいます。
そこで、テストデータ自体もsupabase db reset
と同時に投入するために、supabase/seed.sql
を使用します。
supabase/seed.sql
は、supabase db reset
を実行するときに自動的に実行される SQL ファイルです。
supabase init
を実行した時にプロジェクトのsupabase
ディレクトリの中にseed.sql
がデフォルトで作成されています。
デフォルトだと中身は空なので、例として以下の内容にします。
insert into users
(nickname, first_name, last_name, first_name_kana, last_name_kana, email)
values
('テスト名', '太郎','Supabase', 'Tarou','upabase', '[email protected]'),
('テスト名2', '太郎2','Supabase', 'Tarou2','upabase', '[email protected]'),
('テスト名3', '太3','Supabase', 'Tarou3','upabase', '[email protected]');
上記はusers
テーブルにテストデータを3件投入する例になります。supabase db reset
を実行すれば、テストデータが投入されていることを確認できるはずです。
RLS (Row Level Security) を適用する
RLS (Row Level Security) についてもマイグレーションファイルを作成して反映することができます。 まずマイグレーションファイルを作成します。
$ supabase migration new create_rls_policy_for_users_table
以下の内容にします。
-- RLSを有効化
alter table users enable row level security;
-- users ポリシーを作成
-- selectに対しては誰でも可とする
create policy users_select on users for select using (
true
);
-- update, delete, insert に対して、
-- users テーブルの id カラムの値が auth.uid() と一致する場合のみ許可する
-- auth.uid() は、Supabaseにおいて認証されたユーザーのUIDを返す
-- usersテーブルのIDとしてSupabaseのUIDを保存している前提
create policy users_update on users for update using (
(users.id = auth.uid())
);
create policy users_delete on users for delete using (
(users.id = auth.uid())
);
create policy users_insert
on users for insert with check (
(users.id = auth.uid())
);
supabase db reset
でマイグレーションを実行後、ローカルの Supabsae でusers
テーブルを確認すると、以下のように4 active RLS policies
と表示されていることを確認できます。
4 active RLS policies
をクリックすると、以下のように適用したポリシーの詳細を確認できます。
Databsae Function を作成する
Database Function も同じようにマイグレーションファイルで作成できます。
$ supabase migration new create_hello_world_function
以下のような内容にします。
create or replace function hello_world()
returns text
language sql
as $$
select "Hello World!";
$$;
上記のhello_world
関数自体は意味のないものですが、マイグレーションを実行すると以下のようにローカルの Supabase のFunctions
にhello_world
関数が作成されていることを確認できます。
リモートにデータを反映する
これまでに実行したマイグレーションの内容をリモートに反映させてみます。
ローカルとリモートのプロジェクトを紐付ける
まずはじめに、リモートの Supabase に現在のプロジェクトを紐付けます。
supabase link
コマンドを使います。
$ supabase link --project-ref xxxxxxxxxxxxxxxxx
上記のxxxxxxxxxxxxxxxxx
の部分は、自身の Supabase プロジェクト固有のプロジェクト ID です。このプロジェクト ID は、リモートの Supabase のダッシュボードにログインし後の URL から確認できます。具体的には以下のようなフォーマットになっており<project-id>
部分がプロジェクト ID にあたります。
https://supabase.com/dashboard/project/<project-id>
supabase link
を実行すると以下のように表示され、パスワード入力を求められます。これはプロジェクト作成時に設定したデータベースのパスワードです。
$ supabase link --project-ref xxxxxxxxxxxxxxxxx
Enter your database password (or leave blank to skip):
パスワードが正しければ正常に紐付けが完了し、以下のようにFinished supabase link.
と表示されます。
$ supabase link --project-ref xxxxxxxxxxxxxxxxx
Enter your database password (or leave blank to skip):
Finished supabase link.
これで紐付けが完了です。
リモートのマイグレーション反映状況を確認する
紐付けが完了したらsupabase migration list
を実行してローカルとリモートのマイグレーションの反映状況を確認します。
$ supabase migration list
Connecting to remote database...
LOCAL │ REMOTE │ TIME (UTC)
─────────────────┼────────┼──────────────────────
20231104222217 │ │ 2023-11-04 22:22:17
20231105033533 │ │ 2023-11-05 03:35:33
20231105055711 │ │ 2023-11-05 05:57:11
20231105060551 │ │ 2023-11-05 06:05:51
上記を見ると、LOCAL
には5個のマイグレーションが実行されていますが、REMOTE
には何も実行されていないことがわかります。
リモートにマイグレーションを反映する
ここでsupabase db push
コマンドを使うことで、ローカルのマイグレーションをリモートに反映させることができます。
$ supabase db push
以下が実行結果です。
$ supabase db push
Connecting to remote database...
Applying migration 20231104222217_create_users_table.sql...
Applying migration 20231105033533_add_address_to_users_table.sql...
Applying migration 20231105055711_create_rls_policy_for_users_table.sql...
Applying migration 20231105060551_create_hello_world_function.sql...
Finished supabase db push.
上記のように、未反映のマイグレーションがリモートに反映されます。
リモートの Supabase にログインして確認すると、ローカルに作成したテーブルやカラムが反映されていることが確認できると思います。
なお、seed.sql
に記述したテストデータはローカル用でありリモートには反映されません。
他にも色々な状況のために Supabase CLI にはコマンドが用意されています。 全てはここで解説できないため、以下の公式ドキュメントを参考にしてください。
Supabase CLI
The Supabase CLI provides tools to develop your project locally and deploy to the Supabase Platform.
supabase.com
まとめ
Supabase CLI を使うことでデータベースに関連するおおよその操作を行うことができます。
また、マイグレーションファイルが作成、変更履歴として残るため、チーム開発でのデータベースの変更を管理することもできます。
さらにマイグレーションファイルがあれば同じ内容のデータベースを再現することもできるため、開発環境の構築も簡単になります。