[Node] Mysql ORM으로 사용해보기 (2) - 데이터타입, Seed데이터, 모델과 테이블 연동

Kim Tae Won·2022년 1월 19일
0

[Node] ORM 다루기

목록 보기
2/3
post-thumbnail
post-custom-banner

이전 글에 이어서 이번 글에서는 데이터타입과 Seed 데이터 넣기, 모델과 테이블 연동에 대해 알아보자.

1) 데이터타입과 기본값

1. 데이터 타입

// ...
	id: {
	  type: Sequelize.INTEGER
	},
	name: {
	  type: Sequelize.STRING
	},
// ...

각 속성에 설정했던 데이터 타입들은 데이터베이스의 테이블의 각 컬럼의 데이터타입으로 매핑되게 된다. 이때,

  • Sequelize.STRING -> VARCHAR(256)
  • Sequelize.INTEGER -> INTEGER
  • Sequelize.FLOAT -> FLOAT
  • Sequelize.DATE -> DATETIME
    으로 변환되게 된다. 오른쪽의 DB의 데이터타입은 데이터베이스를 배워본 적이 있다면 충분히 알 수 있을 것이다.

더 많은 데이터 타입에 대해 알고 싶다면, Sequelize 공식문서를 참고하자.
여기서 알아두면 좋은 점은 Sequelize.DataTypes.STRINGSequelize.STRING이 동일하다는 점이다.

2. 기본값(defaultValue)

// ...      
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE,
        defaultValue: Sequelize.fn('now')
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE,
        defaultValue: Sequelize.fn('now')
      }
// ...

이것 역시 데이터베이스를 배워보았다면, 그 개념이 명확할 것이다. 말 그대로 기본값이라는 의미로, 데이터를 새롭게 삽입할 때, 해당 컬럼이 비어 있으면(설정해주지 않으면) defaultValue에 있는 값이 자동으로 들어가게 된다.
이전 글에서 본 defaultValue: Sequelize.fn('now') 의 경우 MySQL 데이터베이스에서 사용할 수 있는 now라는 함수를 의미한다. Sequelize ORM에서는 이렇게 데이터베이스에서 지원하는 함수를 나타내기 위해 Sequelize.fn('함수 이름') 형식의 코드를 사용하게 된다. 이런 식으로 데이터베이스 자체의 함수도 사용할 수 있게 된다.

2) Seed 데이터 넣기

Seed 데이터를 넣기 위해서는 아래 작업을 수행해야 한다.

npx sequelize seed:generate --name initialMembers
  • Members 테이블에 넣을 seed 데이터 삽입 코드가 있는 initialMembers라는 이름의 파일을 생성하는 코드이다
    • (생성일자 및 시간)-initialMembers.js 파일이 생성됨
module.exports = {
  async up (queryInterface, Sequelize) {
    await queryInterface.bulkInsert('Members', [
      {
        id: 1,
        name: 'Alex',
        team: 'engineering',
        position: 'Server Developer',
        emailAddress: 'alex@google.com',
        phoneNumber: '010-xxxx-xxxx',
        admissionDate: '2018/12/10',
        birthday: '1994/11/08',
        profileImage: 'profile1.png',
      },
      {
        id: 2,
        name: 'Benjamin',
        team: 'engineering',
   // ...
  • 코드에 실제로 넣을 seed 데이터에 해당하는 JSON 형식의 직원 정보 배열 추가한 뒤, 아래 명령어를 실행해주면 된다.
    npx sequelize db:seed:all

    위와 같이 migrated 되었다고 나오면 성공이다.
    실제로 DB에 잘 들어갔는지 확인해보면,
    매우 잘 들어간 것을 확인할 수 있다.

3) 모델과 테이블 연동

이제 모델과 테이블을 연동해보자. 이미 이전 글에서 Member 모델을 생성을 완료했기 때문에 연결만 해주면 사용이 가능해진다.

1. 모델 수정

하지만 그 전에, 자동으로 생성된 id속성도 다루고 싶다면, Model에 추가해주어야 한다. 나는 Model.init()메소드 내에 맨 위에 아래와 같이 추가해주었다. migrations 내의 파일과 다른점은 DataTypes라는 객체를 받아오기 때문에 Sequelize.INTEGER가 아닌 DataTypes.INTEGER를 사용했다는 점이다.

// ./models/member.js 
class Member extends Model {}
  Member.init(
    {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: DataTypes.INTEGER,
      },
...

2. 모델과 테이블 연동

사실 .models/디렉토리 내의 index.js파일이 우리가 생성한 모델과 DB의 테이블을 연동하는 역할을 해준다.
사실 이미 쓰여져 있는 코드를 그대로 놔두어도 잘 작동한다. 하지만 기본적인 원리를 알아보기 위해 이번엔 직접 써보가면서 배워보자.

먼저 Sequelize 모듈과 설정 파일을 불러오자.

const Sequelize = require('sequelize');
const config = require('../config/config.json');

그리고 development 객체의 설정을 가져와서 sequelize 객체를 만들자.
이렇게 하면 우리가 처음에 설정했던 development 데이터베이스 설정대로 sequelize 객체를 생성해준다.

const = {
  username, password, database, host, dialect
} = config.development;
const sequelize = new Sequelize(database, username, password, {
  host,
  dialect,
});

이제는 모델을 가져와야 한다. 그 전에 ./models/member.js파일을 보면

module.exports = (sequelize, DataTypes) => {
  class Member extends Model {
  //... 생략 ... 

위와 같이 sequlize 객체와 DataTypes를 인자로 받는 함수가 공개되어 있음을 확인가능하다. 따라서 이 두 객체를 넣어주고 실행하면 Model 객체를 생성할 수 있게 된다.

const Member = require('./member')(sequelize, Sequelize.DataTypes);

이제 생성된 모델 객체를 사용하려면 외부에 공개해야 하는데, 관례적으로 db라는 객체에 모델들을 넣어 공개하게 된다. 나중에 다른 테이블이 생긴다면 새로운 모델이 필요할 수 있기 때문이다.

const db = {}
db.Member = Member;

module.exports = db;

그 뒤에는 메인 파일에서 db를 가져와 사용하면 된다. 여기서는 메인 디렉토리의 app.js파일에서 사용해보겠다.

// /app.js
// 특정 디렉토리만 적어줘도 그 아래에 있는
// index.js 파일을 자동으로 찾음
const db = require('./models');

const { Member } = db;

이제 이 Member 모델을 사용해서 데이터베이스 작업을 할 수 있게 된다.

사실 지금까지 작성한 코드를 잘 보면, 원래 기본적으로 작성되어 있던 코드와 그 원리가 같음을 알 수 있다. 따라서 기본코드를 그대로 쓰는 것을 권장한다. 따로 코드 작성을 더 하지 않아도 되고, 모델이 추가되더라도 자동으로 공개가 되기 때문에 우리가 직접 db객체에 추가해주지 않아도 된다.

기본적으로 작성되어 있던 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.js')[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 자체도 db 객체에 담아 공개하는 것을 볼 수 있다. 이를 이용해 테이블 생성을 코드 내부에서도 구현이 가능하다. app.js에서 sync()메소드만 해주면 된다.

const db = require('./models');

db.sequelize.sync();

이제 다음 글에서는 데이터 조회 등 ORM을 이용해 데이터베이스를 다루는 방법에 대해 알아보겠다.

참고

profile
꿈이 너무나 큰 평범한 컴공 대딩에서 취업 성공!
post-custom-banner

0개의 댓글