Hasura のアプリケーション開発において、Hasura の状態は Postgres database schemaHasura metadata に依存していますので、それぞれ Postgres database schema を担当する Database migration filesHasura 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 です。

MigrationFileを適応させるCLIコマンドの例
hasura migrate apply

Hasura metadata とは

Hasura metadata は主に Hasura に関する情報で、テーブル間の Relationship の定義や、アクセスコントロール、Remote Schema の情報等が含まれます。

これを管理するためのファイルが Hasura metadata files です。

MetadataFileを適応させるCLIコマンドの例
hasura metadata apply

実際の手順

アプリケーションの立ち上げ

まずは Hasura と PostgresDB を立ち上げるための docker-compose ファイルを作成します。

docker-compose.yaml
# 立ち上げる
# 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、及びそれらを管理するディレクトリが作成されます。

Screen Shot 2020-08-11 at 0.44.44

metadata には Hasura metadata files が保持されます。この時点で metadata ディレクトリにはかなりのファイルがあるはずですが、ファイルの中身自体はほぼ空です。

Screen Shot 2020-08-11 at 0.45.16

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 にディレクトリが増えているはずです。

Screen Shot 2020-08-11 at 0.53.08

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 のアプリケーション開発に慣れてきたら是非把握したいですね!