LoginSignup
5
2

NestJSのTypeORMの設定(Postgres)

Last updated at Posted at 2020-08-02

NestJS TypeORMの設定 ※postgresql

typeormのバージョンがアップしたので更新

1.構成

1-1.フォルダ構成

.
├── app/ # NestJSのフォルダ
├── .env
├── docker-compose.yml
└── Dockerfile

1-2. ファイル編集

Dockerfile
FROM node:18.12.1
RUN npm i -g @nestjs/cli
WORKDIR /app
docker-compose.yml
version: "3.7"

services:
  app:
    build: .
    env_file:
      - .env
    environment:
      TZ: "Asia/Tokyo"
    ports:
      - 3000:3000
    tty: true
    volumes:
      - ./app:/app

  db:
    image: postgres:15.1
    environment:
      POSTGRES_PASSWORD: postgres
      POSTGRES_USER: postgres
      POSTGRES_DB: test
      TZ: "Asia/Tokyo"
    ports:
      - 5432:5432
    volumes:
      - "./dbdata:/var/lib/postgresql/data"
.env
NODE_ENV=local
# db関連の設定
DATABASE_HOST=db
DATABASE_USER=postgres
DATABASE_PASSWORD=postgres
DATABASE_PORT=5432
DATABASE_DB=test

2. NestJSのプロジェクト生成

docker-compose up -d
docker-compose exec app bash
# container内作業
nest new .
yarn start:dev # localhost:3000で動作確認

3. Configurationのパッケージインストール&確認

3-1. Configurationのパッケージインストール

# container内で作業
yarn add @nestjs/config

3-2. ファイル編集

app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from '@nestjs/config';

@Module({
- imports: [],
+ imports: [ConfigModule.forRoot({ isGlobal: true})],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
app.service.ts
import { Injectable } from '@nestjs/common';
+ import { ConfigService } from '@nestjs/config';

@Injectable()
export class AppService {
+ constructor(private configService: ConfigService) {}
  getHello(): string {
+   console.log(this.configService.get('DATABASE_HOST'), this.configService.get('DATABASE_DB'));
    return 'Hello World!';
  }
}

3-3. 確認

yarn start:dev

※localhost:3000にアクセス
image.png
※環境変数が取得できていることを確認

4. Typeormの設定

4-1. packageインストール

yarn add @nestjs/typeorm typeorm pg

4-2. Typeormの設定反映

app/src/db/database.config.ts
import { Injectable } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { TypeOrmOptionsFactory, TypeOrmModuleOptions } from "@nestjs/typeorm";

@Injectable()
export class TypeOrmConfigService implements TypeOrmOptionsFactory {
  createTypeOrmOptions(): TypeOrmModuleOptions {
    const configService = new ConfigService();
    return {
      type: 'postgres',
      host: configService.get('DATABASE_HOST'),
      port: configService.get('DATABASE_PORT'),
      username: configService.get('DATABASE_USER'),
      password: configService.get('DATABASE_PASSWORD'),
      database: configService.get('DATABASE_DB'),
      entities: [],
      synchronize: false, // 本番環境では必ずfalse
    };
  }
}
app/src/app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from '@nestjs/config';
+import { ConfigModule } from '@nestjs/config';
+import { TypeOrmModule } from '@nestjs/typeorm';
+import { TypeOrmConfigService } from './db/database.config';


@Module({
- imports: [ConfigModule.forRoot({ isGlobal: true})],
+ imports: [
+   ConfigModule.forRoot({ isGlobal: true}), 
+   TypeOrmModule.forRootAsync({ 
+     imports: [ConfigModule], 
+     useClass: TypeOrmConfigService
+   })
+ ], 
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
app/src/db/data-source.ts
import { DataSource } from "typeorm";
import { User } from "./entities/user.entity";

const DATABASE_HOST = process.env.DATABASE_HOST;
const DATABASE_USER = process.env.DATABASE_USER;
const DATABASE_PASSWORD = process.env.DATABASE_PASSWORD;
const DATABASE_PORT = process.env.DATABASE_PORT;
const DATABASE_DB = process.env.DATABASE_DB;
if (!DATABASE_HOST || !DATABASE_USER || !DATABASE_PASSWORD || !DATABASE_PORT || !DATABASE_DB) {
  throw new Error('Enviroment Database Error');
}

const source = new DataSource({
  type: 'postgres',
  host: DATABASE_HOST,
  port: Number(DATABASE_PORT),
  username: DATABASE_USER,
  password: DATABASE_PASSWORD,
  database: DATABASE_DB,
  entities: [],
  migrations: ['src/db/migrations/**/*.ts'], // フォルダを作成すること
  synchronize: false,
})
export default source;

5. Entity作成と設定追加

5-1. Entity作成

app/src/db/entities/user.entity.ts
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity('users')
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  firstName: string;

  @Column()
  lastName: string;

  @Column({ default: true })
  isActive: boolean;
}

5-2. 設定に反映

app/src/db/data-source.ts
+import { User } from "./entities/user.entity";

const source = new DataSource({
  type: 'postgres',
  host: DATABASE_HOST,
  port: Number(DATABASE_PORT),
  username: DATABASE_USER,
  password: DATABASE_PASSWORD,
  database: DATABASE_DB,
- entities: [],
+ entities: ['src/db/**/*.entity.ts'],
  migrations: ['src/db/migrations/**/*.ts'], // フォルダを作成すること
  synchronize: false,
})
app/src/db/database.config.ts
import { Injectable } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { TypeOrmOptionsFactory, TypeOrmModuleOptions } from "@nestjs/typeorm";
+import { User } from "./entities/user.entity";

@Injectable()
export class TypeOrmConfigService implements TypeOrmOptionsFactory {
  createTypeOrmOptions(): TypeOrmModuleOptions {
    const configService = new ConfigService();
    return {
      type: 'postgres',
      host: configService.get('DATABASE_HOST'),
      port: configService.get('DATABASE_PORT'),
      username: configService.get('DATABASE_USER'),
      password: configService.get('DATABASE_PASSWORD'),
      database: configService.get('DATABASE_DB'),
-     entities: [],
+     entities: [User],
      synchronize: false, // 本番環境では必ずfalse
    };
  }
}
package.json
  "scripts": {
    ...
+   "typeorm": "npx typeorm-ts-node-commonjs",
+   "migration:generate": "yarn typeorm -d src/db/data-source.ts migration:generate",
+   "migration:run": "yarn typeorm -d ./src/db/data-source.ts migration:run",
+   "migration:revert": "yarn typeorm -d src/db/data-source.ts migration:revert"
  },

6. migration実行確認

6-1. migration:generateの実行

 yarn migration:generate src/db/migrations/init

※実行結果
image.png

6-2. migration:runの実行

yarn migration:run

※実行結果
image.png

6-3. migration:revertの実行

yarn migration:revert

※実行結果
image.png

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2