저장을 습관화
NestJS TypeORM 연습 기록 - migrations 본문
사용하는 이유
예를 들어 mysql workbench에서 SQL 명령어를 직접 입력하여
테이블의 컬럼명을 바꾸었다고 해보자.
이 작업은 DB 테이블 내에서만 적용하는 것이 아니라
개발 중인 프로젝트의 entities에서도 적용해주어야한다.
DB 테이블에만 적용하고 entitiy를 적용하지 않았거나, 작업 중 실수로 잘못된 값을 입력하여
entities와 DB의 내용이 서로 다를 경우 불일치 에러가 발생할 수 있다.
0. package.json
지난 시간에 작성했던 내용 중
NestJS TypeORM 연습 기록 - DB 생성, 테이블 생성, seeding(초기 데이터 입력)
지난 시간에 app.module과 .env에 사용할 DB 서버의 위치를 지정해 주었으므로, DB를 생성, 사용해 보기로 https://ctrs.tistory.com/466 NestJS - TypeORM을 위한 app.module.ts 설정 기록 메모... @nestjs/typeorm, typeorm, mys
ctrs.tistory.com
사용할 명령어들
{
"scripts": {
"typeorm": "ts-node --require tsconfig-paths/register ./node_modules/typeorm/cli.js",
"db:migrate": "npm run typeorm migration:run -- -d ./dataSource.ts",
"db:migrate:revert": "npm run typeorm migration:revert -- -d ./dataSource.ts",
"db:create-migration": "npm run typeorm migration:create -- ./src/migrations/",
"db:generate-migration": "npm run typeorm migration:generate -- ./src/migrations -d ./dataSource.ts"
},
}
1. 테스트를 위해 Mentions 엔티티에서 'category' 컬럼의 이름을 'type'으로 수정하였다.
별도의 수정 내역이 없었으니 DB에서는 여전히 category이다.
2. /scr 디렉토리 하단에 migrations 폴더 생성
사전에 설정 파일 dataSouce.ts에서 migration 내용을 읽어오는 경로를 지정한 곳이다.
dotenv.config();
const dataSource = new DataSource({
migrations: [__dirname + '/src/migrations/*.ts'],
});
export default dataSource;
3. migration 파일 생성 및 설정
$ npm run db:create-migration
> a-nest@0.0.1 db:create-migration
> npm run typeorm migration:create -- ./src/migrations/
> a-nest@0.0.1 typeorm
> ts-node --require tsconfig-paths/register ./node_modules/typeorm/cli.js migration:create ./src/migrations/
Migration C:\(중략)\a-nest\src/1699769430697-migrations.ts has been generated successfully.
/src 하단에 (숫자)-migraions.ts 파일이 생성되었다.
구분을 위해서 파일의 이름을 알아보기 쉽게 변경하고,
이 파일을 /src/migrations 폴더에 집어넣는다.
파일의 내용도 수정한다.
적용하고 싶은 내용을 up에,
실수한 경우 롤백을 위해서 적용하기 전으로 돌리는 내용을 down에 넣는다.
- before
import { MigrationInterface, QueryRunner } from "typeorm"
export class Migrations1699769430697 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
}
public async down(queryRunner: QueryRunner): Promise<void> {
}
}
- after
import { MigrationInterface, QueryRunner } from 'typeorm';
export class Migrations1699769430697 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
// up에는 수행할 내용이 들어간다
// 예시
await queryRunner.query(
'ALTER TABLE `mentions` RENAME COLUMN `category` TO `type`',
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
// down에는 수행하기 전, 혹은 수행된 내용을 롤백할 내용이 들어간다
// 예시
await queryRunner.query(
'ALTER TABLE `mentions` RENAME COLUMN `type` TO `category`',
);
}
}
.query() 함수명에서 알 수 있듯이 안에는 쿼리문이 들어가야한다.
수작업으로 입력하지 않고
npm run db:generate-migration 명령어를 사용하는 방법도 있으나
불안정한 경우가 있으니 100% 의지하지 말고 조심하도록 하자
4. 변경 내용을 DB에 적용
$ npm run db:migrate
> a-nest@0.0.1 db:migrate
> npm run typeorm migration:run -- -d ./dataSource.ts
> a-nest@0.0.1 typeorm
> ts-node --require tsconfig-paths/register ./node_modules/typeorm/cli.js migration:run -d ./dataSource.ts
query: SELECT VERSION() AS `version`
query: SELECT * FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = '00_nestjs_typeorm' AND `TABLE_NAME` = 'migrations'
query: SELECT * FROM `00_nestjs_typeorm`.`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 `mentions` RENAME COLUMN `category` TO `type`
query: INSERT INTO `00_nestjs_typeorm`.`migrations`(`timestamp`, `name`) VALUES (?, ?) -- PARAMETERS: [1699769430697,"Migrations1699769430697"]
Migration Migrations1699769430697 has been executed successfully.
query: COMMIT
dataSource.ts에 설정된대로
/src/migrations 폴더 하단의 파일들을 찾아 변경 내용을 DB에 적용한다.
변경 내용이 적용된 DB에서도 컬럼명이 type으로 확인되었다.
그리고 이 내역은 DB 내 migrations 테이블에 저장된다.
나중에 다른 테이블에도 마이그레이션을 적용하기 위해 npm run db:migrate 명령어를 사용하더라도
migrations 테이블에 있는 내용은 제외되기 때문에
/src/migraions 폴더에서 'chageColumnNameFromCategoryToType.ts' 파일을 지워줄 필요는 없다.
5. 롤백
$ npm run db:migrate:revert
> a-nest@0.0.1 db:migrate:revert
> npm run typeorm migration:revert -- -d ./dataSource.ts
> a-nest@0.0.1 typeorm
> ts-node --require tsconfig-paths/register ./node_modules/typeorm/cli.js migration:revert -d ./dataSource.ts
query: SELECT VERSION() AS `version`
query: SELECT * FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = '00_nestjs_typeorm' AND `TABLE_NAME` = 'migrations'
query: SELECT * FROM `00_nestjs_typeorm`.`migrations` `migrations` ORDER BY `id` DESC
1 migrations are already loaded in the database.
Migrations1699769430697 is the last executed migration. It was executed on Sun Nov 12 2023 15:10:30
GMT+0900 (대한민국 표준시).
Now reverting it...
query: START TRANSACTION
query: ALTER TABLE `mentions` RENAME COLUMN `type` TO `category`
query: DELETE FROM `00_nestjs_typeorm`.`migrations` WHERE `timestamp` = ? AND `name` = ? -- PARAMETERS: [1699769430697,"Migrations1699769430697"]
Migration Migrations1699769430697 has been reverted successfully.
query: COMMIT
DB에서 롤백 확인
DB내 migrations 테이블에도 내용이 사라졌음을 확인
다음 db:migrate 명령 실행 시에는
다시 'chageColumnNameFromCategoryToType.ts'의 내용도 포함되어 마이그레이션 될 것이다.
'공부 > node.js' 카테고리의 다른 글
에러 기록 - DB에 createdAt이 9시간 전으로 저장되는 현상 (0) | 2023.11.18 |
---|---|
NestJS - 세션 방식 로그인에서 서버를 재시작해도 로그인이 풀리지 않게 하려면.. (0) | 2023.11.18 |
NestJS TypeORM 연습 기록 - DB 생성, 테이블 생성, seeding(초기 데이터 입력) (0) | 2023.11.12 |
NestJS - TypeORM을 위한 app.module.ts 설정 기록 (0) | 2023.11.11 |
에러 기록 - Could not resolve dependency: @nestjs/typeorm@"*" from the root project (0) | 2023.11.11 |