src/database/database.service.ts

import { ConfigService } from '@nestjs/config';
import { TypeOrmModuleOptions } from '@nestjs/typeorm';

export class DataBaseService {
  constructor(private config: ConfigService) {}

  public getTypeOrmConfig(): TypeOrmModuleOptions {
    return {
      type: 'mariadb',
      host: this.config.get('DB_HOST'),
      port: +this.config.get('DB_PORT'),
      username: this.config.get('DB_USERNAME'),
      password: this.config.get('DB_PASSWORD'),
      database: this.config.get('DB_NAME'),
      synchronize: this.config.get('NODE_ENV') !== 'prod',
      logging: this.config.get('NODE_ENV') !== 'prod',
      entities: [
        'dist/example1/entities/example1.entity{.ts,.js}',
        'dist/example2/entities/example2.entity{.ts,.js}',
        'dist/example3/entities/example3.entity{.ts,.js}',
        'dist/example4/entities/example4.entity{.ts,.js}',
        ...
      ],
      migrationsTableName: 'migration',
      migrations: ['src/database/migrations/*{.ts,.js}'],
      cli: {
        migrationsDir: 'src/database/migrations',
      },
    };
  }
}

 

src/database/database.module.ts

import { Module } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';

@Module({
  imports: [ConfigService],
})
export class DatabaseModule {}

 

src/app.module.ts

import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
import * as Joi from 'joi';
...
import { DataBaseService } from './database/database.service';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      ...
    }),
    ...
    TypeOrmModule.forRoot(new DataBaseService(new ConfigService()).getTypeOrmConfig()),
    ...
  ],
  controllers: [],
  providers: [],
})
export class AppModule {}

 

src/write-type-orm-config.ts

 

import { DataBaseService } from './database.service';
import { ConfigService } from '@nestjs/config';
import fs = require('fs');
import * as dotenv from 'dotenv';
import * as path from 'path';

dotenv.config({ path: path.resolve(__dirname, '../../.env.prod') });

const configData = JSON.stringify(
  new DataBaseService(new ConfigService()).getTypeOrmConfig(),
  null,
  2,
);
fs.writeFile('ormconfig.json', configData, err => {
  if (err) {
    console.error(err);
    return;
  }
  console.log('⭐️⭐️⭐️ ormconfig.json has been created ⭐️⭐️⭐️');
});

 

package.json

{
  ...
  "scripts": {
    ...
    "pretypeorm": "ts-node -r tsconfig-paths/register src/database/write-type-orm-config.ts",
    "typeorm": "ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli.js",
    "typeorm:migration:generate": "cross-env NODE_ENV=prod npm run typeorm -- migration:generate -n",
    "typeorm:migration:run": "cross-env NODE_ENV=prod npm run typeorm -- migration:run"
  },
  ...
}

 

migration 생성

npm run typeorm:migration:generate user  

 

TypeORM 에서 migration 을 사용하기 위해서는 먼저 DB 와 커넥션을 할 수 있는 config 파일이 필요한데 위에서는 그 파일을 write-type-orm-config.ts 로 생성되게 하고 script 에서 그 파일을 읽어들일 수 있게 설정해주었다.

 

migration 에 필요한 config 파일을 따로 만들고 app.module.ts 에 TypeORM 을 직접 정의해 줄 수 있는데 그렇게 될 경우 유지보수가 힘들어지고 하나의 설정을 변경하면 다른 설정도 변경해주어야 하기 때문에 database.service 클래스를 만들어서 cofing 파일에서도 사용하고 app.module.ts 에서도 사용할 수 있도록 해주었다.

 

위 설정에서 가장 어렵고 힘들었던 점은 entities 의 경로를 지정해주는 것이었는데 entities: [Cat, Dog, Animal] 처럼 entity 클래스를 넣어줄 경우 write-type-orm-config.ts 에서 entities 의 경로를 null 로 받는 문제가 있었다. 그래서 entity 들의 파일 경로를 위와 같이 하나하나 지정해주었다. 만약 entity 간의 relationship 설정이 되어 있다면 관계 설정에 맞게 순서대로 entity 를 지정해주어야 한다.

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기