anvil-app-serverのデータ管理について

<h2>前書き</h2>
`anvil-app-server`でアプリが動作させられるようになったのはいいのですが、[Anvil](https://anvil.works/)のサイトで作成した`News Aggregater`アプリを動かそうとしても、すんなりとは動いてくれないようで。。。
ちょっと調査してみました。

<h4>前提</h4>
- Anvilで[News Aggregator](https://anvil.works/learn/tutorials/database-backed-apps)アプリを作成済みであること。

<h4>環境</h4>
- Ubuntu 20.04 LTS 日本語 Remix
- Hyper-V マネージャー 10.0.18362.1
- anvil-app-server v1.1

<h2>News Aggregatorアプリのダウンロードと実行</h2>
アプリを作成すると、`View history`から`git clone`コマンドでダウンロードできます。

"View history"をクリックし、
![anvil_newsaggrigator_download_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667657/5609ecee-dab2-7876-bc56-69b93deb96a8.png)

"Clone with Git"をクリックし、
![anvil_newsaggrigator_download_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667657/49cd9a10-8602-8117-3892-7f6d2571985c.png)

"git clone ssh://～"の行をコピーしてコマンドで実行。
![anvil_newsaggrigator_download_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667657/91f53d9f-74e9-23f4-6b87-1bc71e50000b.png)

```bash
git clone ssh://XXXX@anvil.works:2222/324IEWAMVBYU2Y77.git News_Aggregater
```
※`XXXX`にはAnvilサイトに登録したアカウントのメールアドレスが入る。
※二要素認証を有効にしているとSSHパブリックキーを使用しないといけない為、使っている場合は一時的に二段階認証を外しておく。Gitにパブリックキー登録してあればすんなりいけると思いますが。

`anvil-app-server`でアプリケーションを起動。

```bash
anvil-app-server --app News_Aggregater
```
`http://localhost:3030`にブラウザでアクセス。
![anvil_app_server_url.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667657/48bb2fdc-9270-159d-62bc-8bb7ac3a13df.png)

でいきなりエラー。
![anvil_app_server_NewsAggrigator_error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667657/22dc1b5f-c26c-9e74-927c-802c3361b494.png)

<h2>問題点</h2>
News Aggrigatorアプリでは記事の`category`を`categories`テーブルに予め登録し、そこから選択する方法をとっているのですが、アプリにはテーブルのデータが含まれていないため、「空のデータ」でエラーになる。

<h2>anvil-app-serverのPostgreSQLへpgadmin4でアクセス</h2>
`anvil-app-server`は独自のPostgreSQLサーバーを含んでいるので、そちらにアクセスする。

- Username : postgres
- Password : (anvil-app-serverを実行したディレクトリ)/.anvi-data/postgres.password内に記載
- Port : (anvil-app-serverを実行したディレクトリ)/.anvi-data/db/postmaster.opts内に記載

が、見たところ、アプリで必要なはずの`articles`テーブルも`categories`テーブルもなし。
![anvil_db_tables.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667657/04e5cfb0-0a04-c6ae-5c86-22597adf8e84.png)

とりあえず、存在しているテーブルの中身を見ていくと、`app_storage_tables`テーブル内にアプリで作成したテーブルの情報を発見。
![anvil_db_app_storage_tables.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667657/f80f0436-9f55-6d23-db7f-49ecb8da4e0f.png)

また、`create-anvil-app`コマンドで作成できるtodoアプリを使ってデータの作成を見ていくと、`app_storage_data`テーブルにデータが追加されていることが判明。
![anvil_db_app_storage_tables.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667657/3b850d90-7258-a2cb-2e08-7fc9f16b9dc4.png)

<h2>つまりどういうことか</h2>
ここまでのことから、

- アプリで使用するテーブルの情報は、`app_storage_tables`テーブルにJSON形式で格納される。
- アプリからデータにアクセスする場合は、`app_storage_tables`テーブルの情報を元に、`app_storage_data`テーブルのJSON形式のデータにアクセスする。

どんなアプリを作ってもデータ層とロジック層の整合が取れるという観点では、メタテーブルを使うのは考えられなくもないですが、素人の心を挫く仕組みではあります。

<h2>その他</h2>
どのようなデータ管理なのか、少し見えてきたところで、データのインポートをしてみようと、Anvilのサイトに戻って、データのダウンロードを行ってみました。
が、ダウンロードしたデータもすんなりインポートできる内容ではありません。
今回のNews Aggrigatorの`categories`テーブルの場合、

| ID | name |
|:---|:-----|
|[65114][57547127]|entertainment|
|[65114][57547131]|business|
|[65114][57547132]|travel|
|[65114][57547134]|sport|

の様になっており、このデータをローカルDBのメタテーブルと整合が取れた形でJSON形式データを書き込まなければなりません。
※IDのカラムは「おそらく」Anvilでホストしているサーバーにデータが乗っている際の情報なのでローカルDBではあまり意味がなさそう。直感的にはテーブルIDとrowIDくらいかなという気はします。


<h2>後書き</h2>
有償プランであれば、ある程度融通がきく、とか、適切なアドバイスなりツールの利用なりがある、と想像しますが、無料プランでアプリ作って自前でホストして使うには、少々難易度高いと思います。
まあ、有償プランなら独自ドメインも設定できるようなので、そちらの使い方が本道なのでしょう。