ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • TypeOrm Migration 학습
    공부하기/node.js 2023. 4. 8. 14:10

    * 운영 데이터베이스라고 가정하기 때문에 synchronize: false *

     

    탐색한 마이그에이션 명령 목록

    • typeorm migration:create
      • 비어있는 마이그레이션 파일이 생성된다.
      • 생성된 마이그레이션 파일에 변경하고자 하는 스키마 sql문을 작성한다.
      • migration:run 명령을 통해 적용한다.
    • typeorm migration:generate
      • 변경된 내용을 감지하고, 변경 사항을 새로운 마이그레이션 파일로 생성한다.
      • 자동으로 변경 내용을 sql문으로 생성해준다.
      • migration:run 명령을 통해 적용한다.
    • typeorm schema:sync 
      • migration 파일이 따로 생성되지 않는다.
      • 엔티티를 업데이트 한 후 typeorm schema:sync 명령으로 마이그레이션을 진행한다.

     

    migration:create vs migration:generate

    generate의 경우 테이블의 컬럼을 변경할 때 drop한 후 재생성하는 방식으로 동작한다.

    운영중인 데이터베이스라면 데이터유실이 발생할 수 있기 때문에 production에서는 사용하지 않아야겠다 라고 생각했다.

     

    migration:create vs schema:sync

    schema:sync의 경우 데이터베이스의 모든 테이블과 프로젝트의 모든 엔티티를 비교한 후 sync를 맞춘다

    보통 개발자들은 혼자 일하는것이 아니기 때문에 예상치 못한 결과를 초래할 가능성이 높다고 판단했다.

    예를들어 나는 Student 엔티티만 수정하고 schema:sync 명령을 실행했는데 갑자기 Student를 제외한 다른 엔티티의 변경도 함께 적용되는 말도 안되는 문제가 발생할 가능성이 있다.

    이유는 동료 개발자 또는 내가 과거에 테스트 하려고 엔티티를 수정했고 그걸 모르고 schema:sync 명령을 수행했다면 정말 말도 안되는 일이 운영중인 데이터베이스에서 일어날 수 있다.

     

    선택 : migration:create

     

    내가 migration:create 명령을 선택한 이유는 가장 안전하다고 판단했기 때문이다.

    sql문 또한 내가 직접 작성하여 내가 의도한 작업만 데이터베이스에 적용되기 때문에 예측할 수 없는 오류를 피할 수 있다고 생각했다.

     

    migration:create 체험하기

    사전 작업

     

    1. 마이그레이션에 사용되는 data-source.ts 파일을 수정한다.

    {
    	...
    	synchronize: false,
    	migrations: ['src/migrations/*.ts'],
    }

     

    2. 변경하려는 엔티티를 미리 수정한다.

    {
    	...
    	@Column({ type: 'int', default: 0 }) // 추가
      	tempTestField: string;
    }

     

    3. package.json → script typeorm 추가

    "script": {
      ...
      "typeorm": "ts-node ./node_modules/typeorm/cli.js",
      "migration:run": "ts-node ./node_modules/typeorm/cli.js migration:run -d src/data-source.ts",
      "migration:revert": "ts-node ./node_modules/typeorm/cli.js migration:revert -d src/data-source.ts",
    }

    -> -d 옵션을 통해 data-source.ts의 경로를 지정해줄 수 있습니다.

     

    4. 마이그레이션 파일 생성

    npm run typeorm migration:create -n src/migrations/파일명

     

    생성 결과 -> 마이그레이션 파일 정상 생성

    npm run typeorm migration:create -n src/migrations/ddl-update     
    
    > new-nest-survey@0.0.1 typeorm
    > ts-node ./node_modules/typeorm/cli.js migration:create src/migrations/ddl-update
    
    Migration /Users/limsm/Documents/limsm/new-nest-survey/src/migrations/1680934248360-ddl-update.ts has been generated successfully.

     

    마이그레이션 파일 수정

    import { MigrationInterface, QueryRunner } from 'typeorm';
    
    export class ddlUpdate1680934248360 implements MigrationInterface {
      public async up(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.query(`
            ALTER TABLE survey ADD COLUMN tempTestField INT DEFAULT 0;
            `);
      }
    
      public async down(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.query(`
            ALTER TABLE survey DROP COLUMN tempTestField;`);
      }
    }

     

     

    4. 마이그레이션 up

    npm run migration:run

     

    결과

    > new-nest-survey@0.0.1 migration:run
    > ts-node ./node_modules/typeorm/cli.js migration:run -d ./data-source.ts
    
    query: SELECT VERSION() AS `version`
    query: SELECT * FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = 'survey' AND `TABLE_NAME` = 'migrations'
    query: CREATE TABLE `migrations` (`id` int NOT NULL AUTO_INCREMENT, `timestamp` bigint NOT NULL, `name` varchar(255) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB
    query: SELECT * FROM `survey`.`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: 
            ALTER TABLE survey ADD COLUMN tempTestField INT DEFAULT 0;
            
    query: INSERT INTO `survey`.`migrations`(`timestamp`, `name`) VALUES (?, ?) -- PARAMETERS: [1680934248360,"ddlUpdate1680934248360"]
    Migration ddlUpdate1680934248360 has been  executed successfully.
    query: COMMIT

     

    5. 마이그레이션 down

    npm run migration:revert

     

    결과

    > new-nest-survey@0.0.1 migration:revert
    > ts-node ./node_modules/typeorm/cli.js migration:revert -d ./data-source.ts
    
    query: SELECT VERSION() AS `version`
    query: SELECT * FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = 'survey' AND `TABLE_NAME` = 'migrations'
    query: SELECT * FROM `survey`.`migrations` `migrations` ORDER BY `id` DESC
    1 migrations are already loaded in the database.
    ddlUpdate1680934248360 is the last executed migration. It was executed on Sat Apr 08 2023 15:10:48 GMT+0900 (대한민국 표준시).
    Now reverting it...
    query: START TRANSACTION
    query: 
            ALTER TABLE survey DROP COLUMN tempTestField;
    query: DELETE FROM `survey`.`migrations` WHERE `timestamp` = ? AND `name` = ? -- PARAMETERS: [1680934248360,"ddlUpdate1680934248360"]
    Migration ddlUpdate1680934248360 has been  reverted successfully.
    query: COMMIT

    tempTestField 컬럼이 존재하지 않는다.

     

     

Designed by Tistory.