TypeORMを使って、Express + Docker + MySQLの環境を構築する
TypeORMとは、Typescript用のORマッパーです。TypeORMを使って、Express + Docker + MySQLの環境構築からマイグレーションまでを行います。
OSはMacを使います。Node、Yarn、Dockerが既にインストールされていることを前提に進めます。扱うツールなどのバージョンは以下の通りです。
Node | Yarn | Express | TypeScript | MySQL |
---|---|---|---|---|
16.4.2 | 1.22.11 | 4.17.1 | 4.4.3 | 5.7.10 |
環境構築
プロジェクトのフォルダを作成します。
❯ mkdir typeorm-sample
❯ cd typeorm-sample
TypeORMをインストールします。
❯ yarn add typeorm
NodeでTypeScriptを使いたいため、typescriptとts-nodeをインストールします。
❯ yarn add -D typescript ts-node
typeorm initコマンドで、TypeORMの利用に必要なファイルを生成します。更にMySQLとExpress、Dockerも入れます。
❯ yarn typeorm init --database mysql --express --docker
Project created inside current directory.
ファイルを確認すると、docker-compose.ymlが生成されています。docker-compose.ymlの中身を見るとmysql 5.7のimageが設定されているので、そのまま使います。
❯ ls
README.md ormconfig.json src
docker-compose.yml package-lock.json tsconfig.json
node_modules package.json yarn.lock
起動
Dockerを立ち上げて、MySQLを使えるようにします。
❯ docker compose up
docker-compose.ymlに書かれている情報を確認して、MySQLに接続します。
❯ docker compose exec mysql /bin/bash
❯ mysql -utest -ptest
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| test |
+--------------------+
2 rows in set (0.00 sec)
接続が確認できました。
続いてサーバーを起動します。
❯ yarn
❯ yarn start
yarn run v1.22.11
warning package.json: No license field
$ ts-node src/index.ts
Express server has started on port 3000. Open http://localhost:3000/users to see results
http://localhost:3000/usersにアクセスすると、以下のJSONが画面に表示されます。
[{"id":1,"firstName":"Timber","lastName":"Saw","age":27},{"id":2,"firstName":"Phantom","lastName":"Assassin","age":24}]
これはyarn typeorm init
した際に、デフォルトでuserテーブルとそれに関連するデータが作成されたためです。
mysql> show columns from user;
+-----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| firstName | varchar(255) | NO | | NULL | |
| lastName | varchar(255) | NO | | NULL | |
| age | int(11) | NO | | NULL | |
+-----------+--------------+------+-----+---------+----------------+
4 rows in set (0.01 sec)
テーブルの作成
次はTypeORMのマイグレーション機能を使って、テーブルを作成します。
Entityの作成
最初にEntityを定義します。Entityとはテーブルの構造をクラス構文で表現したものです。今回はTODOリストを題材に必要なカラムを用意します。
TODOを保存するための、テーブルの定義は以下にします。
テーブル名:task
カラム論理名 | カラム物理名 | 型 |
---|---|---|
ID | task_id | integer |
タイトル | title | varchar |
期日 | due_date | date |
状態 | status | tinyint |
作成日 | created_at | datetime |
更新日 | updated_at | datetime |
これを元にEntityを書いていきます。
import {
Entity,
Column,
PrimaryGeneratedColumn,
CreateDateColumn,
UpdateDateColumn,
} from 'typeorm';
@Entity()
export class Task {
@PrimaryGeneratedColumn()
readonly task_id: number;
@Column('varchar', { length: 20, nullable: false })
title: string;
@Column('date', { nullable: false })
due_date: Date;
@Column('tinyint', { width: 1, default: 1 })
status: number;
@CreateDateColumn()
readonly created_at?: Date;
@UpdateDateColumn()
readonly updated_at?: Date;
}
Entityの書き方は、以下が参考になります。
マイグレーションファイルの作成
マイグレーションファイルを作成します。
-nは必須のパラメータで、ファイル名を指定します。
❯ yarn ts-node node_modules/.bin/typeorm migration:generate -n Task
実行後は、src/migration/1635378767371-Task.ts
のようにファイルが作成されます。1635378767371の部分は、タイムスタンプです。
import {MigrationInterface, QueryRunner} from "typeorm";
export class Task1635378767371 implements MigrationInterface {
name = 'Task1635378767371'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`CREATE TABLE \`task\` (\`task_id\` int NOT NULL AUTO_INCREMENT, \`title\` varchar(20) NOT NULL, \`due_date\` date NOT NULL, \`status\` tinyint(1) NOT NULL DEFAULT '1', \`created_at\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), \`updated_at\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), PRIMARY KEY (\`task_id\`)) ENGINE=InnoDB`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP TABLE \`task\``);
}
}
- upメソッド:実際にマイグレーションの際に実行されるクエリです
- downメソッド:マイグレーションのロールバックの際に利用されるクエリです
マイグレーションの実行
❯ yarn ts-node node_modules/.bin/typeorm migration:run
反映されているマイグレーションを確認します。
❯ yarn ts-node node_modules/.bin/typeorm migration:show
[X] Task1635378767371
✨ Done in 1.53s.
もし、1つ前のマイグレーションをロールバックしたい場合は、以下のコマンドを実行します。
❯ yarn ts-node node_modules/.bin/typeorm migration:revert
念のため、MySQLに接続して、taskテーブルのカラム一覧を確認した所、問題なく作成されていました。
mysql> show columns from task\G
*************************** 1. row ***************************
Field: task_id
Type: int(11)
Null: NO
Key: PRI
Default: NULL
Extra: auto_increment
*************************** 2. row ***************************
Field: title
Type: varchar(20)
Null: NO
Key:
Default: NULL
Extra:
*************************** 3. row ***************************
Field: due_date
Type: date
Null: NO
Key:
Default: NULL
Extra:
*************************** 4. row ***************************
Field: status
Type: tinyint(1)
Null: NO
Key:
Default: 1
Extra:
*************************** 5. row ***************************
Field: created_at
Type: datetime(6)
Null: NO
Key:
Default: CURRENT_TIMESTAMP(6)
Extra:
*************************** 6. row ***************************
Field: updated_at
Type: datetime(6)
Null: NO
Key:
Default: CURRENT_TIMESTAMP(6)
Extra: on update CURRENT_TIMESTAMP(6)
6 rows in set (0.00 sec)
以上です。
参考
Discussion
現在のTypeORMのバージョンではこの手順でマイグレーションが動作しませんでした