Creating migrations & metadata / Hasura チュートリアル
TweetHasura のアプリケーション開発において、Hasura の状態は Postgres database schema
と Hasura metadata
に依存していますので、それぞれ Postgres database schema
を担当する Database migration files
と Hasura metadata
を担当する Hasura metadata files
を git で管理し、状況に応じて 適応/復元
をすれば、同じ環境を再現することができます。
Postgres database schema
は Postgres に関する情報で、ここにはテーブルスキーマや View, Function などが含まれます。Hasura metadata
は主に Hasura に関する情報で、テーブル間の Relationship の定義や、アクセスコントロール、Remote Schema の情報等が含まれます。
基本的にはこれらのファイルでは、テーブルの「レコード」は管理されないので、レコードも再現したい場合には seed
という概念を使うこともできます。
Postgres database schema とは
連携している Postgres の schema 情報です。具体的にはテーブルの名前、テーブルの構造、View や Functions といった Postgres に関連する部分の情報です。
Hasura cosole 等、Hasura の機能を通してテーブルを作った場合、連携している PostgresDB に Hasura から SQL が発行されてテーブルが作成されます。結果として、実は Hasura にはテーブルの構造に関する情報は保持されていません。ですから、テーブル構造に関する情報は Postgres database schema
に含まれています。
これを管理するためのファイルが Database migration files
です。
hasura migrate apply
Hasura metadata とは
Hasura metadata
は主に Hasura に関する情報で、テーブル間の Relationship の定義や、アクセスコントロール、Remote Schema の情報等が含まれます。
これを管理するためのファイルが Hasura metadata files
です。
hasura metadata apply
実際の手順
アプリケーションの立ち上げ
まずは Hasura と PostgresDB を立ち上げるための docker-compose ファイルを作成します。
# 立ち上げる
# docker-compose up --build
# container を落とすことにより、DB, Metadata を消去する
# docker-compose down
version: "3.6"
services:
postgres:
image: postgres:12
restart: always
environment:
POSTGRES_PASSWORD: postgrespassword
graphql-engine:
image: hasura/graphql-engine:latest
ports:
- "8080:8080"
depends_on:
- "postgres"
restart: always
environment:
HASURA_GRAPHQL_DATABASE_URL: postgres://postgres:postgrespassword@postgres:5432/postgres
HASURA_GRAPHQL_ENABLE_CONSOLE: "true"
HASURA_GRAPHQL_ENABLED_LOG_TYPES: startup, http-log, webhook-log, websocket-log, query-log
その後以下コマンドを実行して立ち上げます
docker-compose up
Hasura CLI をインストールする
Hasura の状態管理をする上で Hasura CLI が必要です。以下手順にしたがってインストールしてください。
https://hasura.io/docs/1.0/graphql/manual/hasura-cli/install-hasura-cli.html#install-hasura-cli
以降は Hasura をグローバルにインストールした前提で進めていきます。(npm パッケージとしてローカルにインストールした場合は、こちらの注意点をご確認ください)
Hasura init で Database migration files と Hasura metadata files、及びそれらを管理するディレクトリを作成する
以下コマンドを実行すると色々聞かれますが、今回は全部 Yes で問題ありません。
hasura init
すると Database migration files と Hasura metadata files、及びそれらを管理するディレクトリが作成されます。
metadata
には Hasura metadata files が保持されます。この時点で metadata
ディレクトリにはかなりのファイルがあるはずですが、ファイルの中身自体はほぼ空です。
migrations
ディレクトリには Database migration files
が保持されます。現時点では何もありません。
Hasura console を hasura ディレクトリで実行する
以下コマンドを、今作成した hasura ディレクトリで実行します。もっと具体的にいえば config.yaml があるディレクトリで実行します。
hasura console
するとあらたに Hasura console が立ち上がります。これは Hasura を立ち上げたときに自動的に localhost:8080 にできる Hasura console とは機能が違います。便宜的に CLI を使って立ち上げた hasura console を real hasura console と呼ぶことにします。
Real hasura console で、テーブルを作成する
なんでもいいですが Real hasura console
の GUI でテーブルを作成してください。注意して欲しいのは localhost:8080 にある console ではない点です。
Real hasura console
の GUI でテーブルを作成すると /hasura/migrations
にディレクトリが増えているはずです。
migrations ディレクトリの中身
この中にある up.sql
に、先ほど実行した「テーブルの作成」に該当する SQL コマンドが記録されています。
つまり migration file
の招待は、Hasura console を操作した結果 PostgresDB に発行された SQL
そのものです。
これを記録しておいて、別の DB に実行すれば、同じ状態になるというわけです。
metadata ディレクトリの中身
わかりずらいですが、テーブルを作成したことで metadata ディレクトリ内のファイルも変化しています。
具体的には今回のテーブル作成であれば、tables.yaml
に今回作成されたテーブルが追加されているはずです。
この情報は、テーブルの構造に関する情報そのものではありません。テーブルの構造に関する情報そのものは migrations
ディレクトリで管理している Database migration files
に含まれています。
では tables.yaml
に書かれている情報は一体何でしょうか。これは、Hasura に対して、DB の特定のテーブルを「認識 = track」させた、という情報です。
試しにこのファイの中身を全て消すと(今はやめておきましょう。混乱すると思うので)、Hasura の GraphQL からそのテーブルに対して query を発行できなくなります。なぜなら Hasura が PostgresDB のそのテーブルを認識していないからです。
こういった Hasura に関する情報が metadata
ディレクトリには含まれています。
migrations は自動的に随時作成される、metadata は現在の状態だけを表している
DB migration 用ファイルは、DB に対する操作がされるたびに、一ファイル作成されます。例えばテーブルを作って、カラムを追加して、カラムの type を変更したら、三回操作があったので、3ファイル作成されます。
Metadata のほうは違います。これはあくまで現在の状態を表す情報が、ファイルとして保持されます。ドキュメントには「スナップショット」という表現がされていますね。
どう違うかというと、例えば DB migration のほうは、テーブルを作って、そして作ったものを削除すると、元に戻りますが、ファイルは3つ作成されます。しかし、Metadata のほうは元に戻ったので結果として metadata
ディレクトには全く変更がない状態、つまり元に完全に戻ります。これが DB migration 用ファイルと、metadata ファイルが作られる条件の違いです。
git commit しよう
ではこうして作られた metadata と migrations をコミットしましょう。 これでいつでも復元できる準備が整いました。
docker-compose down で全情報をリセット
docker-compose down
をすると完全に docker インスタンスを落とすことになるので、全ての情報がリセットされます。つまりテーブルの情報も Hasura の状態もリセットされます。
ここから先ほどの状態を復元していきましょう。
hasura migrate status, apply
では最初に migration つまり DB の復元から行います。
まず hasura migrate status
と実行すると、色々ある migration のうち、何も適応していないということがわかります。migtation の適応具合を hasura migtate status
で確認することができます。
では実際に migrations を適応させましょう。
hasura migrate apply
これでテーブル構造が戻りました。
hasura metadata apply
次に hasura metadata apply
を実行するとメタデータが適応されます。
これで全て戻りました。
テーブルの中身が戻っていない?
テーブルに含まれるレコードはこの手順では基本的に復元できません。
ただこれを実行する手段もあります。それについては seed
の項目で説明します!
Hasura real console で作業をすることが大切
ということで hasura console
で real console を立ち上げて、その GUI で操作をすることが非常に大切です。そうしないと migration ファイルが生成されないからです。
そうして生成された migration ファイルと metadata ファイルを git で管理すれば、いつでも安全に状態を戻せるというわけです!!!
このあたりは、ある程度 Hasura のアプリケーション開発に慣れてきたら是非把握したいですね!