ライブラリのインストール
shell
npm install --save @nestjs/typeorm typeorm mysql2
環境変数を読み込む準備
以下の記事を参考にして、 .env
からデータベースのパラメータを設定する準備をしてください。
本番環境と開発環境ではパラメータが異なるはずなので、環境変数で出し分けが必要なためです。
.env ファイルを作成
.env
にデータベースの設定情報を記載します。
.env
# App Configration
APP_PORT=3000
# Database ORM configuration
TYPEORM_CONNECTION=mysql
TYPEORM_HOST=localhost
TYPEORM_PORT=3306
TYPEORM_USERNAME=nestjs
TYPEORM_PASSWORD=password
TYPEORM_DATABASE=nestjs
TYPEORM_SYNCHRONIZE=false
app.module.ts の設定
app.module.ts
を以下のように編集し、 TypeORM の依存関係を定義します。
app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule, ConfigService } from '@nestjs/config';
import configration from './config/configration';
import { TypeOrmModule } from '@nestjs/typeorm';
import { NotesModule } from './notes/notes.module';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
load: [configration],
}),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
useFactory: (configService: ConfigService) => ({
type: 'mariadb',
host: configService.get<string>('database.host'),
port: configService.get<number>('database.port'),
username: configService.get<string>('database.username'),
password: configService.get<string>('database.password'),
database: configService.get<string>('database.database'),
synchronize: configService.get<boolean>('database.synchronize'),
autoLoadEntities: true,
charset: 'utf8mb4',
}),
inject: [ConfigService],
}),
NotesModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Entity を作成する
新しい Entity を作成してみます。
notes/entities/note.entity.ts
import { Column, Entity } from 'typeorm';
@Entity('notes')
export class Note {
@Column('uuid', { primary: true, generated: 'uuid' })
id: string;
@Column('varchar', { length: 255 })
title: string;
}
サブモジュールに Entityを登録する
notes/notes.module.ts
に作成した Entity を登録します。
notes/notes.module.ts
import { TypeOrmModule } from '@nestjs/typeorm';
import { Note } from './entities/note.entity';
import { Module } from '@nestjs/common';
@Module({
imports: [TypeOrmModule.forFeature([Note])],
})
export class NotesModule {}
このサブモジュールは app.module.ts
で読み込みます。 imports
の中の NotesModule
です。
app.module.ts
imports: [
ConfigModule.forRoot({
isGlobal: true,
load: [configration],
}),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
useFactory: (configService: ConfigService) => ({
type: 'mariadb',
host: configService.get<string>('database.host'),
port: configService.get<number>('database.port'),
username: configService.get<string>('database.username'),
password: configService.get<string>('database.password'),
database: configService.get<string>('database.database'),
synchronize: configService.get<boolean>('database.synchronize'),
autoLoadEntities: true,
charset: 'utf8mb4',
}),
inject: [ConfigService],
}),
NotesModule,
],
マイグレーションを実行する
ライブラリのインストール
shell
npm i -g typeorm
npm install ts-node --save-dev
package.json の追記
package.json
の scripts
に以下を追加します。
package.json
"migration:gen": "ts-node -r dotenv/config -r tsconfig-paths/register ./node_modules/typeorm/cli.js migration:generate -d ormconfig.ts",
"migration:run": "ts-node -r dotenv/config -r tsconfig-paths/register ./node_modules/typeorm/cli.js migration:run -d ormconfig.ts",
"migration:revert": "ts-node -r dotenv/config -r tsconfig-paths/register ./node_modules/typeorm/cli.js migration:revert -d ormconfig.ts",
"migration:show": "ts-node -r dotenv/config -r tsconfig-paths/register ./node_modules/typeorm/cli.js migration:show -d ormconfig.ts",
scripts
全体は以下のようになっています。
package.json
"scripts": {
"build": "nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"start": "nest start -b swc",
"start:dev": "nest start --watch -b swc",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
"migration:gen": "ts-node -r dotenv/config -r tsconfig-paths/register ./node_modules/typeorm/cli.js migration:generate -d ormconfig.ts",
"migration:run": "ts-node -r dotenv/config -r tsconfig-paths/register ./node_modules/typeorm/cli.js migration:run -d ormconfig.ts",
"migration:revert": "ts-node -r dotenv/config -r tsconfig-paths/register ./node_modules/typeorm/cli.js migration:revert -d ormconfig.ts",
"migration:show": "ts-node -r dotenv/config -r tsconfig-paths/register ./node_modules/typeorm/cli.js migration:show -d ormconfig.ts",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"test": "jest",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json"
},
ormconfig.ts を作成
マイグレーション実行時に読み込む設定ファイルを用意します。
ormconfig.ts
import { DataSource } from 'typeorm';
export const dataSource: DataSource = new DataSource({
type: 'mysql',
host: process.env.TYPEORM_HOST,
port: process.env.TYPEORM_PORT
? parseInt(process.env.TYPEORM_PORT, 10)
: 3306,
username: process.env.TYPEORM_USERNAME,
password: process.env.TYPEORM_PASSWORD,
database: process.env.TYPEORM_DATABASE,
synchronize: process.env.TYPEORM_SYNCHRONIZE === 'true',
entities: [__dirname + '/**/*.entity{.ts,.js}'],
migrations: [__dirname + '/migrations/**/*{.ts,.js}'],
timezone: 'Z',
charset: 'utf8mb4',
});
マイグレーションのコマンド
- マイグレーションファイルの生成
- マイグレーションのステータス確認
- マイグレーションの実行
shell
npm run migration:gen -- ./migrations/CreateNoteTable
npm run migration:show
npm run migration:run
npm run migration:gen -- ./migrations/CreateNoteTable
では、生成されるマイグレーションファイルの名前を指定しています。
参考までに、コマンドの実行ログを載せます。
shell
$ npm run migration:show
> tejun-note-backend@0.0.1 migration:show
> ts-node -r dotenv/config -r tsconfig-paths/register ./node_modules/typeorm/cli.js migration:show -d ormconfig.ts
[ ] CreateNoteTable1691912295169
fj@fjshnoMacBook-Pro: ~/workspace/dev/tejun-note-backend (main *%=)
$ npm run migration:run
> tejun-note-backend@0.0.1 migration:run
> ts-node -r dotenv/config -r tsconfig-paths/register ./node_modules/typeorm/cli.js migration:run -d ormconfig.ts
query: SELECT VERSION() AS `version`
query: SELECT * FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = 'nestjs' AND `TABLE_NAME` = 'migrations'
query: SELECT * FROM `nestjs`.`migrations` `migrations` ORDER BY `id` DESC
0 migrations are already loaded in the database.
1 migrations were found in the source code.
1 migrations are new migrations must be executed.
query: START TRANSACTION
query: CREATE TABLE `notes` (`id` varchar(36) NOT NULL, `title` varchar(255) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB
query: INSERT INTO `nestjs`.`migrations`(`timestamp`, `name`) VALUES (?, ?) -- PARAMETERS: [1691912295169,"CreateNoteTable1691912295169"]
Migration CreateNoteTable1691912295169 has been executed successfully.
query: COMMIT
コマンドを実行すると、データベースにテーブルが作成できます。
参考
データベースを立ち上げるために使った docker-compose.yml
docker-compose.yml
version: '3'
services:
mariadb:
image: 'bitnami/mariadb:10.6'
ports:
- '3306:3306'
volumes:
- 'mariadb_data:/bitnami/mariadb'
environment:
- ALLOW_EMPTY_PASSWORD=yes
- MARIADB_DATABASE=nestjs
- MARIADB_USER=nestjs
- MARIADB_PASSWORD=password
- TZ="Asia/Tokyo"
volumes:
mariadb_data:
driver: local