tblsを使ってテーブルのPlantumlを生成&vscodeで表示までしてみる

# はじめに

テーブル定義を元にER図が作れたら便利ですよね。

この記事では、[tbls](https://github.com/k1LoW/tbls)を使ってテーブル定義を元にしたuml（[PlantUML](https://github.com/plantuml/plantuml)）を生成し、そのumlをvscodeで確認するまでの手順を紹介します。

## 開発マシーン
OS: macOS Catalina
バージョン: 10.15.4

## Plantumlの環境構築
必要なものは以下3点。

- Javaの実行環境
- Graphvizっていうソフトウェア
- PlantUMLっていうvscodeのプラグイン

### Java
Javaは以下のサイトからダウンロードして、インストールしてください。
https://java.com/ja/
ちなみに私のJava環境は、すでに以下の状態だったのでスルー。

```
$ java --version
java 13.0.1 2019-10-15
Java(TM) SE Runtime Environment (build 13.0.1+9)
Java HotSpot(TM) 64-Bit Server VM (build 13.0.1+9, mixed mode, sharing)
```

### Graphviz
Graphvizは、以下のようにインストール

```
brew install install graphviz
```

### PlantUML
PlantUMLのプラグインは以下のものをインストール

![スクリーンショット 2021-06-09 9.55.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1371897/ce870aa2-11a3-c5a6-b321-fbc8a1dfea3e.png)

これだけだったはずです！


## tblsの環境構築

tblsを以下のようにインストール

```
brew install k1LoW/tap/tbls
```

こちらもこれだけだったはず。

## tblsを使ってPlantUMLを確認してみる！
環境構築がうまくできたと信じて、実際に **tblsコマンド実行 -> PlantUML生成 -> PlantUML確認** までを試していきます！

### 例1. MySQL

#### MySQLのセッティング

すぐに試したかったので、ローカルPC環境直下にDB・テーブルをセットしました。

```
$ mysql --version
mysql  Ver 8.0.25 for macos10.15 on x86_64 (Homebrew)

$ mysql.server start

$ mysql -uroot

mysql> CREATE TABLE departments (
    department_id int primary key,
    department_name varchar(20)
    ) ENGINE=INNODB DEFAULT CHARSET=utf8;

mysql> CREATE TABLE employees (
    employee_id int primary key,
    department_id int,
    name varchar(20),
    age int,
    CONSTRAINT fk_department_id
        FOREIGN KEY (department_id) 
        REFERENCES departments (department_id)
        ON DELETE RESTRICT ON UPDATE RESTRICT
    ) ENGINE=INNODB DEFAULT CHARSET=utf8;

```

#### PlantUML生成&確認

以下のようにmysqlのプロセスが生きてること確認して、

```
 lsof -i | grep mysql
mysqld    68269 fukazawakeisuke   31u  IPv4 0x3e18e99c4a7abba3      0t0  TCP localhost:33060 (LISTEN)
mysqld    68269 fukazawakeisuke   35u  IPv4 0x3e18e99c4a186ba3      0t0  TCP localhost:mysql (LISTEN)
```


> tbls out my://root:mypass@localhost:33306/testdb -t cacoo -o schema.csv


上記のtblsコマンド例を参考に、以下を実行しました。

```
tbls out my://root:@localhost:3306/hoge -t plantuml -o hoge.plantuml
```

すると先ほど作成したMySQLのテーブル定義が、以下のようにPlantUMLとして生成されていることが確認できます。

```
$ cat hoge.plantuml 
@startuml
!define table(name, desc) entity name as "desc" << (T,#5DBCD2) >>
!define view(name, desc) entity name as "desc" << (V,#C6EDDB) >>
!define column(name, type, desc) name <font color="#666666">[type]</font><font color="#333333">desc</font>
hide methods
hide stereotypes

skinparam class {
  BackgroundColor White
  BorderColor #6E6E6E
  ArrowColor #6E6E6E
}

' tables
table("departments", "departments") {
  column("+ department_id", "int", "")
  column("department_name", "varchar(20)", "")
}
table("employees", "employees") {
  column("+ employee_id", "int", "")
  column("# department_id", "int", "")
  column("name", "varchar(20)", "")
  column("age", "int", "")
}

' relations
"employees" }-- "departments" : "FOREIGN KEY (department_id) REFERENCES departments (department_id)"

@enduml
```

生成したPlantUMLは、vscode上で以下のように確認できます！

![スクリーンショット 2021-05-23 16.55.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1371897/5f374854-9826-5e14-78d5-fbc1edd5bce7.png)


### 例2. BigQuery

#### BigQueryのセッティング

※テーブル（VIEW）の作成をGCPのコンソール上で行いました。
※コンソール上の操作の説明は省略します。

まず以下のコマンドでログインします。

```
gcloud auth application-default login
```

BigQuery内のスキーマとテーブルが、それぞれ以下の状態にセッティングされていることを確認します。

```
$ bq ls
      datasetId       
 -------------------- 
  training_dataset_1

$ bq ls training-project-314502:training_dataset_1
             tableId              Type    Labels   Time Partitioning   Clustered Fields  
 ------------------------------- ------- -------- ------------------- ------------------ 
  departments                     TABLE                                                  
  employee_and_departments_view   VIEW                                                   
  employees                       TABLE                                                  

$ bq query --nouse_legacy_sql \
> 'SELECT * FROM `training-project-314502.training_dataset_1`.INFORMATION_SCHEMA.COLUMNS'
Waiting on bqjob_r474bd2474752300_00000179f5b4a5da_1 ... (0s) Current status: DONE   
+-------------------------+--------------------+-------------------------------+-----------------+------------------+-------------+-----------+--------------+-----------------------+-----------+-----------+--------------+-------------------+------------------------+-----------------------------+
|      table_catalog      |    table_schema    |          table_name           |   column_name   | ordinal_position | is_nullable | data_type | is_generated | generation_expression | is_stored | is_hidden | is_updatable | is_system_defined | is_partitioning_column | clustering_ordinal_position |
+-------------------------+--------------------+-------------------------------+-----------------+------------------+-------------+-----------+--------------+-----------------------+-----------+-----------+--------------+-------------------+------------------------+-----------------------------+
| training-project-314502 | training_dataset_1 | employees                     | employee_id     |                1 | YES         | INT64     | NEVER        | NULL                  | NULL      | NO        | NULL         | NO                | NO                     |                        NULL |
| training-project-314502 | training_dataset_1 | employees                     | department_id   |                2 | YES         | INT64     | NEVER        | NULL                  | NULL      | NO        | NULL         | NO                | NO                     |                        NULL |
| training-project-314502 | training_dataset_1 | employees                     | name            |                3 | YES         | STRING    | NEVER        | NULL                  | NULL      | NO        | NULL         | NO                | NO                     |                        NULL |
| training-project-314502 | training_dataset_1 | employees                     | age             |                4 | YES         | INT64     | NEVER        | NULL                  | NULL      | NO        | NULL         | NO                | NO                     |                        NULL |
| training-project-314502 | training_dataset_1 | employee_and_departments_view | employee_id     |                1 | YES         | INT64     | NEVER        | NULL                  | NULL      | NO        | NULL         | NO                | NO                     |                        NULL |
| training-project-314502 | training_dataset_1 | employee_and_departments_view | department_id   |                2 | YES         | INT64     | NEVER        | NULL                  | NULL      | NO        | NULL         | NO                | NO                     |                        NULL |
| training-project-314502 | training_dataset_1 | employee_and_departments_view | name            |                3 | YES         | STRING    | NEVER        | NULL                  | NULL      | NO        | NULL         | NO                | NO                     |                        NULL |
| training-project-314502 | training_dataset_1 | employee_and_departments_view | age             |                4 | YES         | INT64     | NEVER        | NULL                  | NULL      | NO        | NULL         | NO                | NO                     |                        NULL |
| training-project-314502 | training_dataset_1 | employee_and_departments_view | department_id_1 |                5 | YES         | INT64     | NEVER        | NULL                  | NULL      | NO        | NULL         | NO                | NO                     |                        NULL |
| training-project-314502 | training_dataset_1 | employee_and_departments_view | department_name |                6 | YES         | STRING    | NEVER        | NULL                  | NULL      | NO        | NULL         | NO                | NO                     |                        NULL |
| training-project-314502 | training_dataset_1 | departments                   | department_id   |                1 | YES         | INT64     | NEVER        | NULL                  | NULL      | NO        | NULL         | NO                | NO                     |                        NULL |
| training-project-314502 | training_dataset_1 | departments                   | department_name |                2 | YES         | STRING    | NEVER        | NULL                  | NULL      | NO        | NULL         | NO                | NO                     |                        NULL |
+-------------------------+--------------------+-------------------------------+-----------------+------------------+-------------+-----------+--------------+-----------------------+-----------+-----------+--------------+-------------------+------------------------+-----------------------------+
```

#### PlantUML生成&確認

MySQLの時と同様に、以下のコマンドでPlantUMLを生成します。

```
$ tbls out bq://training-project-314502/training_dataset_1 -t plantuml -o training_dataset_1.plantuml
```

以下のように、生成されたPlantUMLを確認します。

```
$ cat training_dataset_1.plantuml 
@startuml
!define table(name, desc) entity name as "desc" << (T,#5DBCD2) >>
!define view(name, desc) entity name as "desc" << (V,#C6EDDB) >>
!define column(name, type, desc) name <font color="#666666">[type]</font><font color="#333333">desc</font>
hide methods
hide stereotypes

skinparam class {
  BackgroundColor White
  BorderColor #6E6E6E
  ArrowColor #6E6E6E
}

' tables
table("departments", "departments") {
  column("department_id", "INTEGER", "")
  column("department_name", "STRING", "")
}
view("employee_and_departments_view", "employee_and_departments_view") {
  column("employee_id", "INTEGER", "")
  column("department_id", "INTEGER", "")
  column("name", "STRING", "")
  column("age", "INTEGER", "")
  column("department_id_1", "INTEGER", "")
  column("department_name", "STRING", "")
}
table("employees", "employees") {
  column("employee_id", "INTEGER", "")
  column("department_id", "INTEGER", "")
  column("name", "STRING", "")
  column("age", "INTEGER", "")
}

' relations

@enduml

```

こちらも同様に、vscodeでPlantUMLを表示してみました。

![スクリーンショット 2021-06-10 20.28.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1371897/45576532-1e98-ab16-db3a-5b524dd2d0bf.png)