[express.js] ESM문법으로 Sequelize의 Migration을 통해 DB 변경

김지엽·2023년 11월 14일
0
post-thumbnail

1. 개요

이전 포스팅에서 데이터베이스를 설계하고 sequelize를 통해서 mysql과 연동까지 했다. 하지만 설계한 테이블에서 컬럼을 수정하거나 변경, 삭제 하는등 테이블을 변경해야 하는 상황이 생길 수 있다. 이때 sequelize를 통해 데이터베이스를 수정하는 방법은 여러가지가 있다.

  1. migration 파일을 통해서 데이터베이스를 수정한다.
  2. 직접 mysql로 접속해서 수정 후 sequelize 모델도 같이 수정한다.
  3. mysql로 접속해서 테이블을 삭제하고 sequelize 모델을 수정 후 sync를 통해 동기화 시킨다.

이런 여러가지 방법이 있지만 보통은 첫번째 방법을 사용할 것이다.

그 이유는 두번째 방법을 선택했을때, 데이터베이스와 sequelize 모델을 각각 수정하게 될 경우 일을 두번하게 되는 것이며 수정내용이 많아질수록 효율이 떨어진다.

세번째 방법은 아주 효율적이지만 현재 데이터베이스에 데이터가 없을 경우 또는 삭제해도 되는 경우에만 사용할 수 있는 조건부적인 방법이기 때문이다.

따라서 보통 데이터베이스를 수정해야 할 경우에 migration 파일을 작성해서 수정하는 것이 일반적이다.

2. 수정할 내용

오늘 튜터님께 이전에 제출했던 과제에 대해 다음과 같은 피드백을 받았다.

"상품의 상태를 관리할때 'FOR_SALE', 'SOLD_OUT'을 사용한다고 하면 이 두가지 키워드만 들어올 수 있도록 데이터 타입을 ENUM으로 지정하라"

따라서 이번에 테이블에서 변경해야 할 내용은 상품의 상태 컬럼의 데이터 타입을 ENUM으로 바꿔주는 것이다.

3. migration 파일 작성하기

터미널에서 다음 명령어를 통해 migration 파일을 생성 할 수 있다.

$ npx sequelize-cli migration:generate --name 파일이름 --models-path 모델파일경로

파일을 생성하고 열면 다음과 같은 내용이 있다.

'use strict';

/** @type {import('sequelize-cli').Migration} */
module.exports = {
  async up (queryInterface, Sequelize) {
    /**
     * Add altering commands here.
     *
     * Example:
     * await queryInterface.createTable('users', { id: Sequelize.INTEGER });
     */
  },

  async down (queryInterface, Sequelize) {
    /**
     * Add reverting commands here.
     *
     * Example:
     * await queryInterface.dropTable('users');
     */
  }
};

migration 파일에서 up은 테이블의 변경하고 새로운 상태로 변경하는 역할(업데이트)을 하며, down은 up을 통한 변경사항을 롤백하는 역할을 한다.

up 함수에는 변경내용인 state의 데이터 타입을 ENUM으로 변경하는 작업을, down에는 다시 원래 데이터 타입으로 변경하는 작업을 넣는다. 코드는 다음과 같다.

"use strict";

/** @type {import('sequelize-cli').Migration} */
module.exports = {
    async up(queryInterface, Sequelize) {
        return queryInterface.changeColumn("products", "state", {
            type: Sequelize.ENUM("FOR_SALE", "SOLD_OUT"),
            allowNull: false,
            defaultValue: "FOR_SALE",
        });
    },

    async down(queryInterface, Sequelize) {
        return queryInterface.changeColumn("products", "state", {
            type: Sequelize.STRING(20),
            allowNull: false,
            defaultValue: "FOR_SALE",
        });
    },
};

파일을 작성하고 다음의 명령어를 터미널에 입력한다. 환경변수에 따라 development는 본인에게 맞도록 변경한다.

$ npx sequelize db:migrate --env development

다음과 같이 성공적으로 테이블이 변경된 것을 볼 수 있다.

문제점

위의 과정을 똑같이 따라하다 보면 npx sequelize db:migrate --env development 명령어를 입력하면 다음과 같은 오류가 발생할 수 있다.

이유는 이 프로젝트가 ESM문법 기반이기 때문이다. 하지만 migration 파일은 commonJS 문법으로 생성되기 때문에 파일의 확장자를 js에서 cjs로 변경해야 한다.

참고

migration 파일 작성

profile
욕심 많은 개발자

0개의 댓글