Nest.js - TypeORM + PostgreSQL

맛없는콩두유·2025년 5월 22일
0

프로젝트 구조 설명

src/
├── config/           # 설정 파일들
├── database/         # DB 관련 설정, 마이그레이션, 시드 파일
├── entity/          # TypeORM 엔티티 정의
├── board/           # 게시판 모듈
├── middleware/      # 미들웨어
├── exceptions/      # 예외 처리
├── decorators/      # 커스텀 데코레이터
├── app.module.ts    # 루트 모듈
├── app.controller.ts # 루트 컨트롤러
└── main.ts          # 애플리케이션 시작점

1. TypeORM 설정 상세 가이드

TypeORM이란?

TypeORM은 NodeJS에서 실행되는 ORM(Object-Relational Mapping)으로, 데이터베이스를 객체지향적으로 관리할 수 있게 해주는 도구입니다.

필요한 패키지 설치

npm install @nestjs/typeorm typeorm pg @nestjs/config

각 패키지의 역할

  • @nestjs/typeorm: NestJS와 TypeORM을 통합하는 모듈
  • typeorm: 데이터베이스 ORM 코어 패키지
  • pg: PostgreSQL 데이터베이스 드라이버
  • @nestjs/config: 환경 변수 관리 모듈

TypeORM 설정 파일 구조

import { DataSource } from 'typeorm';
import { config } from 'dotenv';

config({ path: '.env.local' });
export default new DataSource({
  type: 'postgres',
  host: process.env.DB_HOST,
  port: parseInt(process.env.DB_PORT || '5432'),
  username: process.env.DB_USERNAME,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME,
  entities: ['src/**/*.entity.{js,ts}'],
  synchronize: false,
  migrations: ['src/database/migrations/*.ts'],
  migrationsTableName: 'migrations',
});

설정 항목 설명

2. PostgreSQL 설치 및 설정 상세 가이드

PostgreSQL 설치 방법

  1. Windows 사용자
   # chocolatey를 통한 설치
   choco install postgresql
  1. maxOS 사용자
  # homebrew를 통한 설치
   brew install postgresql

데이터베이스 생성 및 설정

CREATE DATABASE simple_board;
CREATE USER myuser WITH PASSWORD 'mypassword';
GRANT ALL PRIVILEGES ON DATABASE simple_board TO myuser;

환경 변수 설정(.env)

npm install dotenv
DB_HOST=localhost
DB_PORT=5432
DB_USERNAME=myuser
DB_PASSWORD=mypassword
DB_NAME=simple_board

3. TypeORM Entity 상세 설명

Entity란?

Entity는 데이터베이스 테이블과 매핑되는 클래스입니다. 각 프로퍼티는 테이블의 컬럼을 나타냅니다.

기본 Entity 구조

src/entity/user.entity.ts:
import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn } from 'typeorm';

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

  @Column({ length: 100 })
  username: string;

  @Column({ unique: true })
  email: string;

  @CreateDateColumn()
  createdAt: Date;

  @UpdateDateColumn()
  updatedAt: Date;
}

데코레이터 설명

  • @Entity(): 클래스가 엔티티임을 선언
  • @PrimaryGeneratedColumn(): 자동 증가 기본 키
  • @Column(): 테이블 컬럼
  • @CreateDateColumn(): 생성 시간 자동 기록
  • @UpdateDateColumn(): 수정 시간 자동 기록

4. TypeORM 관계 설정 상세 가이드

관계 유형 설명

  1. 일대일 (OneToOne)
@OneToOne(() => Profile)
@JoinColumn()
profile: Profile;
  1. 일대다 (OneToMany)
@OneToMany(() => Board, board => board.user)
boards: Board[];
  1. 다대일 (ManyToOne)
@ManyToOne(() => User, user => user.boards)
user: User;

5. TypeORM Migrations 상세 가이드

Migration이란?

데이터베이스 스키마의 버전 관리 시스템입니다. 데이터베이스 구조 변경사항을 코드로 관리합니다.

npm run migration:generate
npm run migration:run

Migration 명령어 설정

package.json:

{
  "scripts": {
    "migration:create": "typeorm migration:create ./src/database/migrations/Migration",
    "migration:generate": "typeorm-ts-node-commonjs migration:generate ./src/database/migrations/Migration -d ./src/database/data-source.ts",
    "migration:run": "typeorm-ts-node-commonjs migration:run -d ./src/database/data-source.ts",
    "migration:revert": "typeorm-ts-node-commonjs migration:revert -d ./src/database/data-source.ts"
  }
}

Migration 파일 예시

import { MigrationInterface, QueryRunner } from "typeorm";

export class CreateUserTable1234567890123 implements MigrationInterface {
    public async up(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.query(`
            CREATE TABLE user (
                id SERIAL PRIMARY KEY,
                username VARCHAR(100) NOT NULL,
                email VARCHAR(255) UNIQUE NOT NULL,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
        `);
    }

    public async down(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.query(`DROP TABLE user`);
    }
}

6. TypeORM Seeding 상세 가이드

Seeding이란?

초기 데이터를 데이터베이스에 삽입하는 프로세스입니다.

Seeding 설정

  1. 패키지 설치
npm install --save-dev typeorm-extension
  1. Seed 파일 생성
  • package.json
"scripts": {
	...
	"seed": "ts-node -r tsconfig-paths/register src/database/seeds/run-seed.ts",
}
  • src/database/seeds/initial.seed.ts
import { DataSource } from 'typeorm';
import { Seeder, SeederFactoryManager } from 'typeorm-extension';
import { User } from '../../entity/user.entity';

export default class InitialSeeder implements Seeder {
  public async run(
    dataSource: DataSource,
    factoryManager: SeederFactoryManager
  ): Promise<void> {
    const userRepository = dataSource.getRepository(User);

    const users = [
      {
        username: 'admin',
        email: 'admin@example.com',
      },
      {
        username: 'user',
        email: 'user@example.com',
      }
    ];

    for (const user of users) {
      await userRepository.save(userRepository.create(user));
    }
  }
}
  • src/database/seeds/run-seed.seed.ts
import { config } from 'dotenv';
import { runSeeders } from 'typeorm-extension';
import dataSource from '../data-source';

// 환경변수 로드
config({ path: '.env.local' });

const runSeeder = async () => {
  try {
    // 데이터베이스 연결 초기화
    await dataSource.initialize();

    // 시더 실행
    await runSeeders(dataSource, {
      seeds: ['src/database/seeds/*.seed.ts'],
    });
  } catch (error) {
    process.exit(1);
  } finally {
    // 연결 종료
    if (dataSource.isInitialized) {
      await dataSource.destroy();
    }
  }
};

runSeeder();

seeding 실행

npm run seed

주의사항 및 팁

  1. 프로덕션 환경에서는 synchronize: false 설정 필수
  2. 민감한 정보는 반드시 환경 변수로 관리
  3. Migration은 항상 테스트 후 적용
  4. Entity 관계 설정 시 순환 참조 주의
  5. Seeding은 개발/테스트 환경에서만 사용
    이 가이드를 통해 NestJS와 TypeORM을 사용하여 PostgreSQL 데이터베이스를 효과적으로 관리할 수 있습니다.
profile
하루하루 기록하기!

0개의 댓글