NestJS TypeORM Migration Table 수정 및 삭제 -3

 이번에는 TypeORM에서 migration을 셋팅하고 이후 글에서는 동작을 하도록 하겠습니다.


이전글 : NestJS TypeORM Migration DB 생성 및 첫 Migration진행 -2


진행을 위해서는 NestJS가 설치 되어 있어야 합니다. 아래 링크를 참고해 주시기 바랍니다.

링크 : nest js - install & Create Project from Linux or Ubuntu


해당 글에서는 Postgres을 사용합니다. 다만 진행의 편리성을 위해 Docker Container를 이용하여 사용합니다. 아래 링크를 참고해 주시기 바랍니다.

링크 : Docker-Compose yaml파일을 이용하여 PostgreSQL를 Local로 구축하기


이제 해당 users테이블에 name컬럼을 추가하겠습니다. 


1. users테이블에 name추가

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

@Entity('users')
export class User {
@PrimaryGeneratedColumn('increment') // 기존 Column
id: number;

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

@Column() // 추가된 컬럼
name: string;
}


2. migration:generate를 진행합니다.

- migration파일을 생성합니다.

$ npm run migration:generate -- [migration 경로]


migration 경로 : migration파일이 생성될 경로입니다. 처음에 db폴더안에 생성하면 됩니다. 기존 파일과 구분짓기 위해서 migration폴더를 생성해서 그 안에 저장하도록 하겠습니다. (ex : db/migrations/[migration 이름]



이제 migration:run을 진행한다.


위 사진처럼 문제가 발생한 것을 알수 있다. 에러 원인중 이미 users 테이블이 존재한다고 하고 있다. 이는 이전 글에서 만들어서 알수 있지만 왜 typeorm에서 users테이블을 또 생성할려고 하는지 확인해야 한다.

// db/migrations/1681509028295-AddName.ts
import { MigrationInterface, QueryRunner } from 'typeorm';

export class AddName1681509028295 implements MigrationInterface {
name = 'AddName1681509028295';

public async up(queryRunner: QueryRunner): Promise<void> {
// migration:generate로 자동 생성 됬으나 typeOrm에서 새로 Table를 생성하는 것으로 쿼리문을 짬
await queryRunner.query(
`CREATE TABLE "users" ("id" SERIAL NOT NULL, "email" character varying NOT NULL, "name" character varying NOT NULL, CONSTRAINT "UQ_97672ac88f789774dd47f7c8be3" UNIQUE ("email"), CONSTRAINT "PK_a3ffb1c0c8416b9fc6f907b7433" PRIMARY KEY ("id"))`,
);
}

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


위 코드에서 up method가 잘못된 것임을 알수 있다. 

// db/migrations/1681509028295-AddName.ts
import { MigrationInterface, QueryRunner } from 'typeorm';

export class AddName1681509028295 implements MigrationInterface {
name = 'AddName1681509028295';

public async up(queryRunner: QueryRunner): Promise<void> {
// migration:generate로 자동 생성 쿼리문 대신 직접 name컬럼이 추가되는 쿼리문 작성
await queryRunner.query(
`ALTER TABLE users ADD COLUMN name character varying NOT NULL`,
);
}

public async down(queryRunner: QueryRunner): Promise<void> {
// migration:revert도 자동생성 쿼리문 대신 직접 작성
await queryRunner.query(`ALTER TABLE users DROP COLUMN name`);
}
}




이제 테이블이 정상적으로 만들어 졌음을 알수 있습니다. 이런 경우처럼 migreation파일을 생성해도 한번정도는 제대로 된 쿼리인지 확인할 필요가 있습니다.


3. 컬럼 삭제 migration

이제 생성한 name컬럼을 삭제하도록 하겠습니다. migration 파일을 아래와 같이 생성합니다.

// db/migrations/1681509937804-DeleteName.ts
import { MigrationInterface, QueryRunner } from 'typeorm';

export class DeleteName1681509937804 implements MigrationInterface {
name = 'DeleteName1681509937804';

public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "users" DROP COLUMN "name"`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "users" ADD "name" character varying NOT NULL`,
);
}
}

이제 migration:run을 실행하면 이전에 생성한 name컬럼이 사라진 것을 알수 있습니다.



댓글

이 블로그의 인기 게시물

Lesson 12_1 프로퍼티 노드(Property Node)

DAQ로 전압 측정하기-2

Lesson 12_2 참조를 이용한 프로퍼티노드(Property Node)