TypeORM migration
TypeORM migration:create
typeorm migration을 시도해보면서 준비한건 몇가지 되지 않았다.
우선, 터미널에서 typeorm migration 파일을 생성하는 명령어.
1
$ npx typeorm migration:create <path/file_name>
예를 들면
npx typeorm migration:create ./src/migrations/default-tables
이런 식으로 사용할 수 있다.
그리고 마이그레이션 실행시 마이그레이션 파일들의 위치를 알려줄 수 있도록 datasource config 부분에 다음과 같이 설정을 추가한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import { DataSource } from 'typeorm' ;
const dataSource = new DataSource ({
type : process . env . TYPEORM_CONNECTION ,
host : process.env.TYPEORM_HOST ,
port : process.env.TYPEORM_PORT ,
username : process.env.TYPEORM_USERNAME ,
password : process.env.TYPEORM_PASSWORD ,
database : process.env.TYPEORM_DATABASE ,
entities : [ __dirname + '/../**/*.entity.{js,ts}' ],
migrations : [ __dirname + '/../migrations/*.{js,ts}' ], // <- 추가한 부분
migrationsTableName : 'migrations' , // <- 추가한 부분
});
export default dataSource ;
TypeORM migration:run
그리고 마이그레이션을 실행하는 명령어는 2가지 정도 사용할 수 있다.
1
2
npx typeorm-ts-node-commonjs migration:run -d ./src/repositories/data-source.ts
1
2
ts-node ./node_modules/typeorm/cli.js migration:run -d ./src/repositories/data-source.ts
현재 typeORM 버전인 0.3.10에서는 두 가지 명령어 모두 다 잘 된다.
그리고 cross Env 설정으로 NODE_ENV를 세팅하려고 위 두 가지 명령어 중 제일 앞에 추가해주면 된다. (두 명령어 모두 가능)
1
2
$ NODE_ENV = develop ts-node ./node_modules/typeorm/cli.js migration:run -d ./src/repositories/data-source.ts
그런데…
Bug
위 명령으로 datasource 인스턴스가 있는 파일을 불러와야 하는데, NODE_ENV 종류별로 나눈 dotenv 설정을 어떻게 해도 가져오질 못한다.
dotenv 값이 텅텅 빈채 data-source.ts파일이 실행되었다.
즉, TypeORM 설정이 전혀 먹히질 않아 dataSource 실행이 되지 않는다.
error.log를 살펴보자니 아무래도 migration 실행시 ts-node
가 돌긴 하지만 정작 작동은 명령어에 지정된 단일파일로만 움직이는 듯 하다.
때문에 app.ts 또는 main.ts에서 import 하고 있는 dotenv.config()
를 가져오지 못하는 문제!
여러가지 방법을 시도해보다가 dotenv 설정 뭉치(?)를 옮겨보았다.
(사실 지저분해 보여서 이 방법은 정말 하고 싶지 않았다.)
보통 dotenv는 프로젝트의 진입점인 app.ts, index.ts, main.ts 등에서 불러오는게 일반적이지만,
console.log로 테스트 해본 결과, 현재의 프로젝트에서는 data-source 파일이 가장 먼저 열렸다.
추가적으로 몇몇 테스트를 더 해보았지만 별다른 문제는 보이지 않았다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// data-source.ts
import { DataSource } from 'typeorm' ;
// ↓ 여기서부터 ----------------------------------
import { config } from 'dotenv' ;
if ( process . env . NODE_ENV === 'production' ) {
config ({ path : './env/.env.production' });
} else if ( process . env . NODE_ENV === 'develop' ) {
config ({ path : './env/.env.dev' });
console . log ( 'process.env.NODE_ENV is ' , process . env . NODE_ENV );
} else if ( process . env . NODE_ENV === 'test' ) {
config ({ path : './env/.env.test' });
} else {
throw new Error ( 'process.env.NODE_ENV IS_NOT_SET!!' );
}
// ↑ 여기까지가 원래 main.ts 상단에 있던 코드 --------
const dataSource = new DataSource ({
type : process . env . TYPEORM_CONNECTION ,
host : process.env.TYPEORM_HOST ,
port : process.env.TYPEORM_PORT ,
username : process.env.TYPEORM_USERNAME ,
password : process.env.TYPEORM_PASSWORD ,
database : process.env.TYPEORM_DATABASE ,
entities : [ __dirname + '/../**/*.entity.{js,ts}' ],
migrations : [ __dirname + '/../migrations/*.{js,ts}' ],
migrationsTableName : 'migrations' ,
});
export default dataSource ;
test code도 실행시켜보고 다른 몇가지 테스트들을 더 해봤지만 딱히 문제는 나타나지 않고 잘 해결 되었다.
자 그럼 실제로 마이그레이션 할 때, 위 명령어는 너무 기니까, script로 정리해두자.
1
2
3
4
5
6
7
8
9
"scripts" : {
"build" : "npx tsc" ,
"start" : "NODE_ENV=develop node dist/main.js" ,
// ...
"typeorm" : "NODE_ENV=develop ts-node ./node_modules/typeorm/cli.js migration:run -d ./src/repositories/data-source.ts"
} ,
TypeORM migration:generate
generate는 설명을 보고서는 과연 실제 product 배포 이후의 단계에서 쓸일이 있을까 싶은데 여튼 개발단계에서는 알아두면 이래저래 요긴하게 쓸 수도 있을 것 같다.
1
2
NODE_ENV = develop npx typeorm-ts-node-commonjs migration:generate ./src/migrations/default-tables -d ./src/repositories/data-source.ts
create와는 달리, 기존에 있는 migration파일과 현재의 entity의 차이를 비교하여 수정 해주는데,
정확히 수정이라기보다 기존 데이터(컬럼)을 drop하고, 명령어에 설정한 파일명으로 새로 만들어 세팅을 한다.
실제 적용해보면 query 부분에 선명한 drop
이 눈에 들어온다.
이미 많은 문서에서도 언급되고 있지만 혹시라도 product로서 운용중인 서비스에서는 주의를 요한다.