Sequelize

Front-end Dev. Hyuk·2020년 9월 7일
0


Course 과정은 11. MVC Design Pattern으로 된 sprint를 진행하였다.
그 안에는 MVC Design pattern과 ORM Intro로 수업을 진행하고 더 자세히 들어가보니 결국 Sequelize라는 것을 배우게 된 것 같다. 처음보았지만 여태 Sprint를 진행한 것 중에서 조금 무난하게 별 어려움 없이 중간단계까지 진행한 것 같다. 기초로 설치와 작동방법에서도 어려움을 항상 느꼈던 나인데 이번에는 공식문서나 이런것을 보고 생각하는 것이 조금 늘었는지 무난하게 2단계 중 1단계를 완성할 수 있었던 것 같았다. 4시간동안 1단계를 진행한 것을 정리해 보았다. 먼저 공식 사이트를 통해 Sequelize를 설치를 하였으며 설치된 것을 package.json을 통해 확인했다. 그 후에 Sequelize - Migrations 문서를 통해 sequelize-cli 를 설치을 했으며, 마이그레이션을 할 수 있도록 돕는 툴로, CLI에서 모델을 생성해주거나, 스키마 적용을 할 수 있도록 도와주는 역할을 한다.설치하지 않으면 테스트를 실행할 수 없다.
공식문서를 참고하면서 작성을 하였으며 Shortly-MVC를 진행하였다.

Sequelize 설치
먼저 Sequelize과 mysql2라이브러리를 설치한다.

Sequelize 설치 : $ npm install --save sequelize

Sequelize CLI 설치 : $ npm install --save-dev sequelize-cli

cli를 통해 ORM을 잘 사용할 수 있도록 bootstraping(프로젝트 초기 단계를 자동으로 설정할 수 있도록 도와주는 일)을 해줘야 한다.

bootstraping : $ npx sequelize-cli init
bootstraping을 하면 아래의 폴더가 자동으로 생성된다.

config/config.json
models/
migrations/
seeders/

테이블을 생성할 데이터베이스를 미리 만들어 준다.
이제 cli설정을 해준다. config폴더의 config.json을 설정해준다.
기본적으로 development, test, production 환경중 development로 설정이 되어 있다.

{
  "development": {
    "username": "root",
    "password": null,
    "database": "database_development",
    "host": "127.0.0.1",
    "dialect": "mysql"
  },
  "test": {
    "username": "root",
    "password": null,
    "database": "database_test",
    "host": "127.0.0.1",
    "dialect": "mysql"
  },
  "production": {
    "username": "root",
    "password": null,
    "database": "database_production",
    "host": "127.0.0.1",
    "dialect": "mysql"
  }
}

설정환경은 코드하는 환경에 따라 변경을 해줄 수 있다. 설정파일은 중요한 개인정보가 들어있어서 gitignore에 등록을 해줘야한다. 설정파일을 git의 관리를 받게하는 대신 환경변수로 사용하는 방법이 있다. dotenv를 다운받아서 사용을 하면 가능하지만 나는 아직 사용을 안했다.

Creating the first Model (and Migration)
모델은 스키마와 비슷하다. 모델생성은 터미널을 이용해서 코드로 만든다.

모델 정의 : $ npx sequelize-cli model:generate --name User --attributes firstName:string,lastName:string,email:string

User라는 이름의 모델을 정의하고 모델의 속성을 작성한다. 타입은 문자열인 경우 string, 숫자인 경우 integer등이 있다. 속성의 다른 정보는 여기서 확인이 가능하다.

이 작업을 하면 models폴더에 users라는 폴더가 자동으로 생성된다. 그리고 migrations폴더에도 생성날짜가 파일명인 파일이 생성된다. 여기까지는 아직 모델을 생성한 것은 아니다. 생성하기 전 모델을 정의만 한것이다. 여기서 migrations 디렉터리에 있는 create-user.js 파일을 보면 up과 down으로 구분되어 각각 createTable과 dropTable을 해주는 코드를 볼 수 있다.

정의된 모델을 생성하는 것을 마이그레이션이라고 부른다.

마이그레이션 : $ npx sequelize-cli db:migrate

마이그레이션 취소 : $ npx sequelize-cli db:migrate:undo

마이그레이션을 하고 생성된 모델안에 데이터를 추가해야하는데 Creating the first Seed : 를 이용해서 추가할 수 있다.

Seed 생성 : $ npx sequelize-cli seed:generate --name demo-user

seeders 디렉터리에 파일이 생긴것을 볼 수 있다. 파일을 확인해보면 마이그레이션 파일과 같은 포맷으로 up과 down으로 구분이 되어있는것을 확인 할 수 있다. 시드를 할때는 up에 있는 코드가 실행되고 시드를 취소할때는 down에 있는 코드가 실행된다.

예를들어 아래와 같이 코드를 작성해준다.

module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.bulkInsert('Users', [{
      firstName: 'John',
      lastName: 'Doe',
      email: 'example@example.com',
      createdAt: new Date(),
      updatedAt: new Date()
    }]);
  },
  down: (queryInterface, Sequelize) => {
    return queryInterface.bulkDelete('Users', null, {});
  }
};

Seed 실행 : $ npx sequelize-cli db:seed:all

Seed 삭제 : $ npx sequelize-cli db:seed:undo

테이블에 데이터가 생성된 것을 확인 할 수 있으며 반복적으로 터미널에서 작동되는것을 보면서 어떻게 동작되는지 확인을 계속했다.

npm test를 작동하면서 test를 진행하였으며,다음과 같이 1단계를 통과했다.

(1-1) ORM 설정
✓ cli를 통해 필요한 파일이 자동으로 만들어졌는지 확인합니다
✓ model/index.js 파일이 유효한지 확인합니다
Executing (default): SELECT 1+1 AS result
✓ mysql에 접속할 수 있는지 확인합니다 (48ms)

================================================================================

🚀 (1-2) 모델 생성
✓ url 모델이 존재해야 합니다
┌─────────┬─────────────┐
│ (index) │ Values │
├─────────┼─────────────┤
│ 0 │ 'id' │
│ 1 │ 'url' │
│ 2 │ 'title' │
│ 3 │ 'visits' │
│ 4 │ 'createdAt' │
│ 5 │ 'updatedAt' │
└─────────┴─────────────┘
✓ url 모델은 요구하는 필드를 갖고 있어야 합니다
✓ url 모델의 각 필드는 정해진 타입으로 생성되어야 합니다
✓ url 모델의 visits 필드는 기본값이 0이어야 합니다

================================================================================

🚀 (1-3) 마이그레이션
Executing (default): describe urls
┌─────────┬─────────────┬────────────────┐
│ (index) │ 0 │ 1 │
├─────────┼─────────────┼────────────────┤
│ 0 │ 'id' │ 'int' │
│ 1 │ 'title' │ 'varchar(255)' │
│ 2 │ 'url' │ 'varchar(255)' │
│ 3 │ 'visits' │ 'int' │
│ 4 │ 'createdAt' │ 'datetime' │
│ 5 │ 'updatedAt' │ 'datetime' │
└─────────┴─────────────┴────────────────┘
✓ 마이그레이션을 했다면, urls 테이블이 존재해야 합니다

1-1은 보는 것과 같이 설치하고 나서 설정만 해주면 통과가 되었고 1-2번부터는 이제 직접 만들었다.
Models에 처음 만든 User.js을 복사하고 나서 그 안의 내용을 이름만 변경하고 url,title,visits로 수정하는 작업을 했는데 1-2에서 문제가 발생하였다. 바로 마지막에 url 모델의 visits 필드는 기본값이 0이라고 하는 것인데 우리는 Visits : DataTypes.INTEGER라고 했더니 통과가 안되었다. 그래서 이걸 해결하기 위해서 API를 찾던 중 다음과 같은것이 나왔다.

Model Instances
As you already know, a model is an ES6 class. An instance of the class represents one object from that model (which maps to one row of the table in the database). This way, model instances are DAOs.

For this guide, the following setup will be assumed:

const { Sequelize, Model, DataTypes } = require("sequelize");
const sequelize = new Sequelize("sqlite::memory:");

const User = sequelize.define("user", {
  name: DataTypes.TEXT,
  favoriteColor: {
    type: DataTypes.TEXT,
    defaultValue: 'green'
  },
  age: DataTypes.INTEGER,
  cash: DataTypes.INTEGER
});

(async () => {
  await sequelize.sync({ force: true });
  // Code here
})();

여기서 이제 favoriteColor를 참고하여 작성을 진행하였더니 통과가 되었다. 그 다음이제 1-3의 문제는 test 폴더에 있는 setup.test.js에 있는 내용들을 참고하여 읽었더니 다음과 같이 되어있었다.

describe('🚀 (1-3) 마이그레이션', () => {
  let urlModel;

  before(() => {
    urlModel = require('../models').url;
  })

  it('마이그레이션을 했다면, urls 테이블이 존재해야 합니다', async () => {
    const [results] = await sequelize.query('describe urls');
    const fieldTypeMap = results.map(r => [r.Field, r.Type])
    console.table(fieldTypeMap)

    expect(fieldTypeMap).to.have.deep.members([
      ['id', 'int'],
      ['url', 'varchar(255)'],
      ['title', 'varchar(255)'],
      ['visits', 'int'],
      ['createdAt', 'datetime'],
      ['updatedAt', 'datetime']
    ])
  });

  after(() => {
    console.log('\n' + '='.repeat(80))
  })
});

그래서 이제 이 새로운 파일을 만들기위해 다시 터미널에서 처음 새로운 폴더를 만드는 것처럼 작성을 하였다.
나는 이것을 처음에 새폴더인 migrations에 만들어진 user을 그냥 복사해서 붙여놓고 안에 있는 내용만 수정을 해서 계속 통과가 안되는 것을 보았으며 그 이유는 내생각엔 생성날짜와 시간들이 다 적혀서 나오기 때문이지 않을까 생각이든다.

npx sequelize-cli model:generate --name urls --attributes title:string,url:string,visits:integer

그 후의 이제 실제로 데이터베이스에 해당 테이블을 생성하려면 db:migrate명령 을 실행해야되기 때문에 앞에서도 해주었지만 또 해줘야 작동이 된다. 아직 실행되지 않은 마이그레이션 파일을 찾는 역할도 해준다.

npx sequelize-cli db:migrate

그 후의 test를 실행해보면 통과가 되는 것을 보았고 내가 만든 파일을 볼 수 있었다.

profile
The Known is finite The unknown is infinite.

0개의 댓글