본문 바로가기
서버 인프라, 백엔드/Sequelizer (Mongo, Mysql)

Sequelizer : Sequelize-cli의 migration 기능으로 운영중 테이블 스키마 변경하기.

by 번데기 개발자 2021. 3. 2.
반응형

sequelize 운영 중 테이블 스키마 변경 문제

 

개발을 하다 보면 sequelize의 테이블을 추가하거나 스키마를 변경해야 할 때가 있습니다..

 

보통 이런 작업을 할 때는 sequlize-cli를 설치하여서 사용합니다.

 

스키마를 변경하기 위해서는 보통 sequelize.drop을 통해 테이블을 제거한 뒤에 sequelize.sync()를 수행해여야 하는데 drop을 수행하게 되면 테이블에 있던 데이터가 모두 삭제가 됩니다. 만약 운영 중이었다면 소중한 데이터가 백업하지 못하고 날아가게 되기 때문에 무척 치명적일 수 있습니다.

 

테이블을 안 날리고 데이터베이스의 스키마와 컬럼을 바꿀 수 있을까 찾아보니 sequelize cli의 migration 기능을 이용하면 쉽게 해결되는 것을 알게 되었습니다.

 

아래와 같이 따라 해 보시면 쉽게 운영 도중 sequelizer를 통해서 DB 컬럼의 자료형이나 테이블 스키마를 변경할 수 있습니다.

 

 

sequelize-cli 설치

 

npm을 통해 글로벌로 sequelize를 설치합니다.

 

global로 설치하면 어디에서나 sequelize 관련 shell 명령어를 사용하실 수 있습니다. :)

 

$sudo npm install -g sequelize-cli

 

 

sequelize-cli init 설정 (옵션)

 

이후 sequelize를 초기화하여야 합니다.

 

$sequelize init

 

해당 명령어를 수행하면 아래와 같은 폴더들이 생성됩니다.

 

  • config
  • seeders
  • migration

 

config 폴더 안에 있는 config.json 파일을 열어서 DB 접속 정보를 수정합니다.

 

위 작업은 꼭 진행하지 않으셔도 됩니다. 

 

이미 sequelizer의 연동이 한번 되었다면 건너뛰셔도 상관없습니다.

 

migration을 위한 js파일 만들기

 

$sequelize migration:create --name backup

위 migration 명령어를 이용하여 backup이라는 migration을 위한 js파일을 생성합니다. (backup이라는 파일명은 제가 임의로 지정한 파일명입니다.)

 

해당 명령어를 실행하면 migration 폴더가 생성되고 migration 폴더 안에 20200227085520-backup.js과 같은 형식의 파일이 생성이 됩니다.

 

migration 파일은 일종의 스냅샷같은 기능을 하는데, 해당 js파일을 이용하여 DB의 스키마 변경을 적용하거나, DB를 스키마 변경 전 특정 시점으로 원복 할 수 있습니다.

 

 

 

migration을 위한 js파일에 up / down 설정하기

 

migration을 위해 만든 js파일을 열어보면 아래와 같이 up과 down이라는 함수 모듈이 있는 js파일을 확인할 수 있습니다.

 

아래 코드는 Products라는 테이블에 thumbnail이라는 String 컬럼값을 추가하거나 제거하는 코드입니다.

 

/** migrations/2012xxxxx.backup.js **/
module.exports = {
    up: (queryInterface, Sequelize) => {
        queryInterface.addColumn(‘Products’, ‘thumbnail’, {
            type: Sequelize.STRING(200)
        });
    },
    down: (queryInterface, Sequelize) => {
        queryInterface.removeColumn(‘Products’, ‘thumbnail’);
    }
};

 

/** config/config.js **/
const dotenv = require('dotenv');

dotenv.config();

module.exports = {
  development: {
    username: 'root',
    password: process.env.DB_PASSWORD,
    database: 'lotto-backend',
    port: process.env.DB_PORT,
    host: '127.0.0.1',
    dialect: 'mysql',
  },
  test: {
    username: 'root',
    password: process.env.DB_PASSWORD,
    database: 'lotto-backend',
    port: process.env.DB_PORT,
    host: '127.0.0.1',
    dialect: 'mysql',

  },
  production: {
    username: 'root',
    password: process.env.DB_PASSWORD,
    database: 'lotto-backend',
    port: process.env.DB_PORT,
    host: '127.0.0.1',
    dialect: 'mysql',
  },
};

 

up과 down은 다음과 같은 의미를 지닙니다.

 

module.export의 up 함수

 

sequelize db:migrate --env development

 

--env 옵션을 줘서 데이터베이스를 선택할 수 있는데, 로컬 개발환경의 데이터베이스를 관리할 때 편리합니다.

 

up 함수에는 새로운 컬럼을 추가하거나 컬럼명을 바꾸거나 해야 할 때, 해당 작업에 대한 내용을 작성합니다.

 

이때 완료가 되면 mysql 테이블의 SequelizeMeta 테이블에 다음과 같이 백업 파일에 대한 js파일명이 insert 됩니다.

 

 

 

 

 

module.export의 down 함수

 

sequelize db:migrate:undo --env development

 

 

up이 실행되기 전의 상태로 데이터베이스를 복원(롤백)하는 명령입니다.

 

이때 down에는 추가한 컬럼을 삭제하는 코드를 작성합니다.

 

롤백은 한 단계씩 수행되며, 원하는 만큼 실행하면 됩니다.

 

롤백이 되면 SequelizeMeta 테이블에 js 파일이 사라지게 됩니다.

 

 

 

 

 

추가 예제 (컬럼을 여러개 추가해야 할 때)

 

만약 컬럼을 여러 개 추가해야 될 때는 다음과 같이 사용합니다.

module.exports = {
    up: function(queryInterface, Sequelize) {
        return [
            queryInterface.addColumn(‘Products’, ‘price’, {
                type: Sequelize.STRING(10)
            }),
            queryInterface.addColumn(‘Products’, ‘description’, {
                type: Sequelize.STRING,
            })
        ];
    },

    down: function(queryInterface, Sequelize) {
        return [
            queryInterface.removeColumn(‘Products’, ‘price’),
            queryInterface.removeColumn(‘Products’, ‘description’)
        ];
    }
};

 

쿼리문을 리터럴 방식으로 작업할 때는 다음과 같이 사용합니다.

module.exports = {
    up: function(queryInterface, Sequelize) {
        var sql = ‘ALTER TABLE Products ADD COLUMN price varchar(255) NOT NULL’;

        return queryInterface.sequelize.query(sql, {
            type: Sequelize.QueryTypes.RAW
        });
    },

    down: function(queryInterface, Sequelize) {
        var sql = ‘ALTER TABLE Products DROP COLUMN price’;

        return queryInterface.sequelize.query(sql, {
            type: Sequelize.QueryTypes.RAW
        });
    }
};

 

migration 수행

 

$sequelize db:migrate –env development

 

위에서 언급했듯이 env 옵션을 통해 디비를 선택할 수 있습니다.

 

디비는 config.json 파일에 세팅된 development, production, test 디비 중에 하나를 선택합니다.

 

마이그레이션을 수행하면 migrations파일에 있는 migration들이 수행되며 아래와 같이 mysql의 SequlizeMeta테이블에 name이라는 컬럼으로 해당 파일 이름이 삽입됩니다.

 

마이그레이션 파일이 여러 개 있더라도 항상 신규 마이그레이션이 동작하는데 그 이유는 mysql migration을 수행하면 생성되는 SequelizeMeta 테이블에서 해당 마이그레이션 파일 이름을 기억하기 때문입니다. 

 

따라서 항상 새로운 migration 파일만 수행되게 됩니다.

 

 

migration 롤백

 

$sequelize db:migrate:undo –env development

위와 같이 롤백을 수행하면 down 명령이 수행되고 이전 migration으로 롤백됩니다.

 

 

 

 

Node.js ORM Sequelize 개발(또는 운영) 도중 컬럼이나 테이블 추가해야 할 때 DB 마이그레이션 하기

Sequelize 마이그레이션

sequelize - Migrations [번역]

 

 

 

반응형