-
How to programmatically migrate the sequelize instead of sequelize-cliJavascript/node.js 2020. 7. 6. 01:33반응형
이 포스팅은 본인의 github pages 기반 블로그에서 이동해온 글 입니다
먼저 sequelize-cli 란?
NodeJS로 RDB를 사용하려면 Sequelize 처럼 편리한 친구도 없을 것이다.
정말?그런 Sequelize를 정말 편리하게 마이그레이션 할 수 있게 도와주는 친구가 하나 있는데, 그게 바로 sequelize-cli 이다. 사용법은 링크를 통해 가서 확인해 보자.
오늘의 포스팅 주제는?
제목 그대로 sequelize-cli 대신, 코드를 작성해서 Sequelize 를 마이그레이션 하는 방법이다.
이걸 왜 하게 됬냐면, 소스코드 내에 RDB의 암호를 설정파일에 하드코딩 해놨었는데
내가 한건 아니고...보안점검때 딱 걸려서 AWS KMS 를 통해 암호를 관리하도록 코드를 수정하게 되었다.
AWS는 정말 없는 서비스가 없는 것 같다... 최고!
아무튼 그래서 코드 싹 다 고쳐서 서버 구동시 KMS 가서 암호 받아오고 DB connection 맺고 이것 저것 다 초기에 수행하도록 코드 수정 후 배포를 딱 했는데...
배포 스크립트에 아래와 같은 코드가 있었고... 해당 스크립트는 KMS로부터 암호를 받기도 전에 수행되는건 둘째 치고... 암호를 외부에서 주입할 수가 없었다.
sequelize db:create sequelize db:migrate
그럼 어떻게? KMS로부터 암호 갖고온 뒤에 마이그레이션을 수행하도록 변경을 해야 했다.
여기까지가 오늘 포스팅을 시작하게 된 이유이다.
그럼 어떻게
베꼈어?먼저 stackoverflow 에 검색을 해 봤다.
다들 google에 검색 먼저 하지만 결국 들어가는데는 여기잖아?제일 처음 들어간 게시물은 how-to-programmatically-run-sequelize-migrations 인데
child_process
를 통해 외부 프로그램 즉 sequelize-cli 를 실행하는 방식이었다.나쁘진 않지만 내가 사용할 수 없는 방법이었다.
나중에 보니 swifty 님이 댓글에 친절하게 umzug 를 언급하고 계셨는데 이제야 봤다...
그러다가 갑자기 든 생각이 sequelize-cli 코드를 까봐서 베껴보자! 였다.
일단 github에 가서 코드를 쭉 보니, 아래가 실제
db:migrate
를 수행하는 함수라는 걸 알아냈다.function migrate(args) { return getMigrator('migration', args).then(migrator => { return ensureCurrentMetaSchema(migrator) .then(() => migrator.pending()) .then(migrations => { const options = {}; if (migrations.length === 0) { helpers.view.log('No migrations were executed, database schema was already up to date.'); process.exit(0); } if (args.to) { if (migrations.filter(migration => migration.file === args.to).length === 0) { helpers.view.log('No migrations were executed, database schema was already up to date.'); process.exit(0); } options.to = args.to; } if (args.from) { if (migrations.map(migration => migration.file).lastIndexOf(args.from) === -1) { helpers.view.log('No migrations were executed, database schema was already up to date.'); process.exit(0); } options.from = args.from; } return options; }) .then(options => migrator.up(options)); }).catch(e => helpers.view.error(e)); }
그중에
migrator
라는 친구를 보니 마지막에migrator.up()
이라는 함수를 호출하는데... 이게 뭔가 하고getMigrator
함수를 쫓아가 보니 아래와 같은 코드가 있었다.export function getMigrator (type, args) { return Bluebird.try(() => { if (!(helpers.config.configFileExists() || args.url)) { helpers.view.error( 'Cannot find "' + helpers.config.getConfigFile() + '". Have you run "sequelize init"?' ); process.exit(1); } const sequelize = getSequelizeInstance(); const migrator = new Umzug({ storage: helpers.umzug.getStorage(type), storageOptions: helpers.umzug.getStorageOptions(type, { sequelize }), logging: helpers.view.log, migrations: { params: [sequelize.getQueryInterface(), Sequelize], path: helpers.path.getPath(type), pattern: /\.js$/, wrap: fun => { if (fun.length === 3) { return Bluebird.promisify(fun); } else { return fun; } } } }); return sequelize .authenticate() .then(() => { // Check if this is a PostgreSQL run and if there is a custom schema specified, and if there is, check if it's // been created. If not, attempt to create it. if (helpers.version.getDialectName() === 'pg') { const customSchemaName = helpers.umzug.getSchema('migration'); if (customSchemaName && customSchemaName !== 'public') { return sequelize.createSchema(customSchemaName); } } return Bluebird.resolve(); }) .then(() => migrator) .catch(e => helpers.view.error(e)); }); }
어휴 길다...바로... Umzug 이친구다.
migrator
는Umzug
의 인스턴스이자 실질적인 Sequelize의 마이그레이션 프레임워크인 것이었다. 유레카!Umzug의 github 사이트를 보면 아래에 너무나도 친절하게 sequelize-migration-hello 를 예제로 알려주고 있다. 얼른 가보자.
Game Over!
그렇다. 끝났다. sequelize-migration-hello 의 README.md에서 너무나도 친절하게 migrate.js 를 통해 마이그레이션을 한다고 알려주고 있었다.
중요한 부분은 아래랑
const umzug = new Umzug({ storage: 'sequelize', storageOptions: { sequelize: sequelize, }, // see: https://github.com/sequelize/umzug/issues/17 migrations: { params: [ sequelize.getQueryInterface(), // queryInterface sequelize.constructor, // DataTypes function() { throw new Error('Migration tried to use old style "done" callback. Please upgrade to "umzug" and return a promise instead.'); } ], path: './migrations', pattern: /\.js$/ }, logging: function() { console.log.apply(null, arguments); }, });
아래의 코드다.
function cmdMigrate() { return umzug.up(); }
Umzug
에는up
외에down
메소드도 있고, 파라미터로 어디까지 수행할지 정할 수도 있으니 undo, redo, reset 등 다양하게 만들 수 있겠다.물론 예제에 다 있다.
반응형'Javascript > node.js' 카테고리의 다른 글
Express에서 URL escape (0) 2020.07.06 Events(1) (0) 2017.08.30