TypeORM(with Docker)の環境構築からマイグレーション実行までの流れ

# TL;DR
この記事では、[TypeORM](https://typeorm.io/ "TypeORM.io")のサンプル作成を題材に、Dockerコンテナへの環境構築からマイグレーション実行までの流れを紹介します。
なお、本記事は以下の参考サイトの内容をもとに、記事執筆時点での変更点（実行するコマンドなど）を加味したものになります。
* [TypeORMを使って、Express + Docker + MySQLの環境を構築する](https://zenn.dev/chida/articles/da18c81674d1a9)

記事執筆時の動作環境は、以下です。
![](https://img.shields.io/badge/Ubuntu-22.04-e95420?logo=ubuntu)![](https://img.shields.io/badge/Node.js-16.17.0-339933?logo=nodedotjs)![](https://img.shields.io/badge/Yarn-1.22.19-2c8ebb?logo=yarn)![](https://img.shields.io/badge/Docker-23.0.1-2496ed?logo=Docker)![](https://img.shields.io/badge/Express-4.18.2-000000?logo=Express)![](https://img.shields.io/badge/TypeScript-4.5.2-3178c6?logo=TypeScript)![](https://img.shields.io/badge/MySQL-8.0.30-4479a1?logo=mysql)

## TypeORMとは
TypeScript(およびJavaScript)で使用可能なORマッパーです。
GitHubのレポジトリは[こちら](https://github.com/typeorm/typeorm)

# 環境構築～コンテナの起動確認
開発用のフォルダを作成します。
```console
$ mkdir typeorm-sample # 任意のフォルダ名でOK
$ cd typeorm-sample
```
TypeORMをインストールします。
```console
$ yarn add typeorm
```
TypeScriptとts-node(NodeでTypeScriptを実行するためのライブラリ)をインストールします。
開発時に使用するものなので、インストール時に`-D`オプションを付加します。
```console
$ yarn add -D typescript ts-node
```
TypeORMのinitコマンドで、TypeORMの利用に必要なファイルを生成します。
使用するデータベースとして、今回はMySQLを指定します。ExpressのインストールとDockerに必要なファイル(docker-compose.yml)の生成も、オプションを指定すれば合わせて実行されます。
```console
$ yarn typeorm init --database mysql --express --docker
```

docker-compose.ymlファイルの生成＆内容確認の完了後、Dockerを立ち上げてMySQLコンテナの起動を確認します。（必要であれば、docker-compose.ymlに記載されたMySQLのバージョン変更などを行ってください）
```console
$ docker compose up
```

docker-compse.ymlの内容をもとに、MySQLへの接続確認を行います。
```console
$ docker compose exec mysql /bin/bash
$ mysql -utest -ptest
Mysql> show databases; # データベースの一覧が表示されればOK
```

MySQLへの接続確認が完了後、Expressサーバの起動を確認します。
```console
$ yarn # 依存関係のインストール
$ yarn start # Expressサーバを起動
```

:::note warn
MySQLの8系を使用する場合、`yarn start`コマンドの実行時に「ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server;」のエラーが発生します。
このエラーは、MySQL8.0でパスワードの認証形式が変更されているものの、Node.jsの「mysql」ライブラリにはまだ実装がされていないことが原因で起こるようです。
本エラーは、以下のSQLをMySQLにてrootユーザで実行することで、エラー解消します。
```sql
ALTER USER 'username'@'%' IDENTIFIED WITH mysql_native_password BY 'password'
```
↑`'username'`と`'password'`は、適切な値に置き換えてください。（筆者の場合、どちらも`'test'`でした。）
:::

Expressサーバの起動後、`http://[ホスト名]:3000/users`にアクセスし、JSON文字列が表示されることを確認します。
このJSONでは、`yarn typeorm init`した際に作成されたuserテーブルのデータが表示されています。

ここまでで、環境構築＆コンテナの起動確認は終了です。

# マイグレーションの実行
最初に、Entity（テーブルの構造をクラス構文で表現したもの）を定義します。冒頭に記載の参考サイトと同様に、`src/entity/Task.ts`を作成します。（ファイルの記載内容は、参考サイトに譲ります）

Entityを定義（`Task.ts`を作成）後、以下のコマンドでマイグレーションファイルを作成します。
```console
$ yarn run typeorm migration:generate -d ./src/data-source.ts ./src/migration/Task
```
注意点は、以下２点です。

:::note warn
注意点１
`src/data-source.ts`ファイル（DataSourceの設定ファイル）に作成したEntityの追加が必要です。
```ts:src/data-source.ts
export const AppDataSource = new DataSource({
  // 不要な属性は省略しています
  // ...
  entities: [User, Task], // <- Taskを追加
  // ...
});
```
:::

:::note warn
注意点２
TypeORMのコマンドの仕様が変わり、`-n`オプションは廃止となっているようです。上記コマンドのように、`-d`オプションでDataSourceの設定ファイルを指定し、コマンドの引数としてマイグレーションファイルの出力先を指定します。
:::

マイグレーションファイルの作成を確認できたら、以下のコマンドで作成したマイグレーションを実行します。
```console
$ yarn run typeorm migration:run -d ./src/data-source.ts
```

:::note warn
マイグレーションファイル作成時と同様に、`src/data-source.ts`ファイルに設定追加が必要です。
```ts:src/data-source.ts
export const AppDataSource = new DataSource({
  // 不要な属性は省略しています
  // ...
  migrations: ["src/migration/**/*.ts"],
  // ↑ マイグレーションファイルのファイルパスを追加
  // ...
});
```
:::

コマンドが正常に終了すれば、定義したEntityのテーブル（今回だとTaskテーブル）がMySQLに作成されています。