Sequelize 튜토리얼(3)_모델 생성

차분한열정·2021년 4월 6일
1

Sequelize 튜토리얼

목록 보기
3/14

University 데이터베이스에 각각 다음과 같은 컬럼들을 가진 총 5개의 테이블을 만들 것이다.

  • Student 테이블(학생) : registrationNum | name | age
  • ScholarshipAccount(장학금용 통장) : accountNum | validDate | balance
  • Grade 테이블(성적) : 추후 설명, 지금은 생성 안 함
  • Course 테이블(수업) : code | title | description |
  • Professor 테이블(교수) : employeeNum | name

그런데 ORM을 통해서 테이블을 생성하려면 일단 모델이라는 것부터 만들어야 한다.

모델을 만드는 방법에는 크게 2가지가 있다. 데이터베이스를 만들 때처럼 sequelize-cli 명령을 사용해도 되고, 코드를 바로 직접 작성해도 된다. 하지만 sequelize-cli 명령을 사용하면 좀더 모범적인 코드를 자동으로 생성해주기 때문에 그냥 sequelize-cli 명령을 사용해서 생성되는 코드들을 살펴보자.

(1) 아래의 명령을 실행하자.

npx sequelize model:generate --name Student --attributes registrationNum:string,name:string,age:integer

이 명령에서

  • model:generate
  • --name 옵션
  • --attributes 옵션

에 주목하자. sequelize에서는 하나의 모델(model)이 데이터베이스에 존재하는 하나의 테이블(table)에 대응되는 개념이다. 그러니까 JS 코드로 모델 객체를 다루는 것이 곧 테이블을 다루는 작업이 되는 것이다. 이건 곧 살펴볼 것이다.
지금 --names 옵션 뒤에는 모델의 이름, Student를 써줬고, --attributes 옵션 뒤에는 Student 모델의 속성들을 써주었다. 이 각각의 속성들이 나중에 테이블의 각각의 컬럼이 된다.

이 명령을 실행하면

(a) models 디렉토리에 Student.js라는 파일이 생성된다.
(b) 그리고 migration 디렉토리에는 (오늘의 날짜/시간)-create-student.js라는 파일이 생성되는데 일단 이것은 나중에 배울 거고, Student.js 파일만 보도록 하자.

models/Student.js 파일

'use strict';
const {
  Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
  class Student extends Model {
    /**
     * Helper method for defining associations.
     * This method is not a part of Sequelize lifecycle.
     * The `models/index` file will call this method automatically.
     */
    static associate(models) {
      // define association here
    }
  };
  Student.init({
    registrationNum: DataTypes.STRING,
    name: DataTypes.STRING,
    age: DataTypes.INTEGER,
  }, {
    sequelize,
    modelName: 'Student',
  });
  return Student;
};

지금 코드를 보면 sequelize 패키지에서 Model이라는 클래스를 가져오고 있다. 그리고 Model 클래스를 상속받는 Student 클래스를 정의했다. 그 안을 보면

  • associate이라는 메소드가 보이는데 이것은 나중에 여러 테이블이 있을 때 테이블 사이의 관계를 설정할 때 내용을 채워주어야 하는 부분이다. 이 부분은 나중에 설명하겠다.

그리고 그 밑을 보면 init이라는 메소드에 크게 2가지 객체를 넣어 실행하고 있다.
첫 번째 객체는 속성 정보가 담긴 객체라는 것을 한 눈에 알 수 있다.
두 번째 객체는 무엇일까? 두 번째 객체에는 이 모델을 생성할 때 적용할 sequelize 객체와 여러 옵션들을 넣어줘야 한다. 지금 보면 함수의 파라미터로 넘어온 sequelize 객체를 그대로 넣어주고, modelName이라는 옵션은 Student라는 것을 알 수 있다. 사실 이 옵션 말고도 또 여러 가지 종류의 옵션들을 넣을 수 있지만 당장 중요한 내용은 아니다. 진도를 나가면서 필요한 옵션들만 하나씩 배울 예정이다. 지금 이 Student.js 파일은 Student 클래스를 리턴하는 함수를 외부에 공개하고 있다. 이 구조를 잘 기억하자.

자, 이제 나머지 모델들도 아래 명령들을 실행해서 생성해보자.

npx sequelize model:generate --name ScholarshipAccount --attributes accountNum:string,validDate:date,balance:integer
npx sequelize model:generate --name Course --attributes courseCode:string,title:string,description:string
npx sequelize model:generate --name Professor --attributes employeeNum:string,age:integer,registrationNum:string

그럼 이제 models 디레토리에

각 모델을 나타내는 파일들이 생겼음을 알 수 있다. 각 파일의 구조는 모두 student.js 파일처럼 어떤 함수를 외부에 공개하는 형태로 되어 있다. 이것들은 모두 models 디렉토리 안의 index.js 파일에서 사용한다. 이 파일을 살펴보자.

models/index.js

'use strict';

const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const basename = path.basename(__filename);
const env = process.env.NODE_ENV || 'development';
const config = require(__dirname + '/../config/config.json')[env];
const db = {};

let sequelize;
if (config.use_env_variable) {
  sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
  sequelize = new Sequelize(
    config.database,
    config.username,
    config.password,
    config
  );
}

fs.readdirSync(__dirname)
  .filter((file) => {
    return (
      file.indexOf('.') !== 0 && file !== basename && file.slice(-3) === '.js'
    );
  })
  .forEach((file) => {
    const model = require(path.join(__dirname, file))(
      sequelize,
      Sequelize.DataTypes
    );
    db[model.name] = model;
  });

Object.keys(db).forEach((modelName) => {
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
});

db.sequelize = sequelize;
db.Sequelize = Sequelize;

module.exports = db;

코드의 내용이 좀 있지만 한 줄씩 읽어보면 별로 어렵지 않다. 간단히 정리해서 말하자면

  • sequelize 객체를 생성하고
  • models 디렉토리에 있는 index.js 파일 이외의 파일들에 대해서 하나씩 sequelize 객체와 Sequelize.DataTypes를 대입하고 실행하면서 각 모델 클래스를 db 객체에 담고
  • 각 모델 클래스의 associate 메소드를 실행하는 코드이다.

그리고 결국엔 이 db 객체를 외부로 공개하고 있다. 자, 다음 글에서 이렇게 공개된 db 객체를 사용해서 원하는 작업을 해보자.

profile
성장의 기쁨

0개의 댓글