Contents

error log - TypeORM migration 할 때 cross ENV 설정 문제

 
 

TypeORM migration

TypeORM migration:create

typeorm migration을 시도해보면서 준비한건 몇가지 되지 않았다.  

우선, 터미널에서 typeorm migration 파일을 생성하는 명령어.  

$ npx typeorm migration:create <path/file_name>

 

예를 들면 npx typeorm migration:create ./src/migrations/default-tables

이런 식으로 사용할 수 있다.
 

그리고 마이그레이션 실행시 마이그레이션 파일들의 위치를 알려줄 수 있도록 datasource config 부분에 다음과 같이 설정을 추가한다.
 

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가지 정도 사용할 수 있다.
 


 npx typeorm-ts-node-commonjs migration:run -d ./src/repositories/data-source.ts    

 


ts-node ./node_modules/typeorm/cli.js migration:run -d ./src/repositories/data-source.ts

 

현재 typeORM 버전인 0.3.10에서는 두 가지 명령어 모두 다 잘 된다.

그리고 cross Env 설정으로 NODE_ENV를 세팅하려고 위 두 가지 명령어 중 제일 앞에 추가해주면 된다. (두 명령어 모두 가능)
 


$ 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 파일이 가장 먼저 열렸다.
추가적으로 몇몇 테스트를 더 해보았지만 별다른 문제는 보이지 않았다.
 

// 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로 정리해두자.
 


"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 배포 이후의 단계에서 쓸일이 있을까 싶은데 여튼 개발단계에서는 알아두면 이래저래 요긴하게 쓸 수도 있을 것 같다.
 


 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로서 운용중인 서비스에서는 주의를 요한다.