[ORM] Nodejs에서 Sequelize 시작하기

김아현·2022년 6월 30일
0

ORM

목록 보기
1/1

이번 포스팅에서는 프로젝트에 시퀄라이즈를 적용해 보면서 알게된 내용들을 공유하고자 합니다.

시퀄라이즈는 ORM

시퀄라이즈는 Nodejs에서 가장 많이 사용하는 ORM 중 하나입니다. 그럼 ORM은 무엇일까요?

ORM(Object-Relational Mapping) 은 객체와 관계형 데이터베이스를 자동으로 매핑하여 비즈니스 로직에 집중할 수 있도록 데이터처리 로직을 추상화시키는 것을 의미합니다.

여기서 객체와 관계형 데이터베이스를 매핑시킨다는 것은 데이터베이스의 데이터에 객체로 접근할 수 있다는 것이고, 데이터처리 로직을 추상화한다는 것은 객체의 메소드로 쿼리문을 작성할 수 있다는 것을 뜻합니다.

그래서 ORM을 사용하게 되면, SQL문과 비즈니스로직 코드가 함께 있을 때보다 코드의 가독성이 높아지게 됩니다. 또한 DB의 기능을 추상화함으로써 데이터베이스의 변경에도 유연하게 대처할 수 있습니다.

반면에 Raw Query보다는 속도가 느리고, 객체 중심으로만 설계하게 되면 프로젝트 규모가 커질수록 생산성이 저하되는 단점이 존재합니다. 그렇기 때문에 ORM을 제대로 사용하려면 DB에 대한 이해가 반드시 필요합니다.

시퀄라이즈 시작하기

설치

시퀄라이즈에서는 Postgres, MySQL, MariaDB, Sqlite, SQL Server 관계형 데이터베이스를 지원합니다. 아래를 참고하여 원하는 데이터베이스를 설치합니다.

# One of the following:
$ npm install pg pg-hstore # Postgres
$ npm install mysql2   # 그냥 mysql은 지원하지 않습니다.
$ npm install mariadb
$ npm install sqlite3
$ npm install tedious # Microsoft SQL Server

시퀄라이즈를 설치합니다.

npm install sequelize

시퀄라이즈를 조금 더 쉽고 효과적으로 사용하기 위해 cli를 선택적으로 설치할 수 있습니다.

npm install sequelize-cli

sequelize-cli를 설치하면 콘솔에 sequelize 명령어를 사용할 수 있고 초기 ORM 설정을 수월하게 할 수 있습니다. 초기화를 해보겠습니다.

sequelize init

그러면 아래와 같이 4개의 폴더가 생성되는 것을 확인할 수 있습니다.

.     
|-- config
|   `-- config.json
|-- migrations     
|-- models
|   `-- index.js    
|-- seeders   
  • config : 데이터베이스 연결에 필요한 정보들을 담아둔 폴더. 개발, 운영, 테스트 등 상황에 맞는 데이터베이스 정보를 사용할 수 있다.
  • migrations : 데이터베이스의 변경 기록을 담은 파일들을 보관하는 폴더. 데이터베이스에 적용하거나 이전 설정으로 되돌릴 수 있다.
  • models : 각 테이블에 대한 필드 타입 및 정보를 정의하고 테이블에 대한 객체를 모아준다.
  • seeders : 테이블에 자동으로 기본 데이터를 넣고 싶은 경우에 사용한다.

환경변수 설정

config 폴더 안에 config.json 파일이 있습니다. 데이터베이스의 연결정보는 노출되면 위험하기 때문에 환경변수를 설정해줘야 하는데, .json 파일 특성 상 모듈을 임포트 할 수 없기 때문에 .js 파일로 변경해야 합니다. 파일이름을 config.js로 바꿉니다.

그리고 .env 파일에 데이터베이스의 실제 정보를 작성합니다.

DB_HOST = DB 주소
DB_PORT = DB 포트번호
DB_NAME = DB 이름
DB_USER = 유저이름
DB_PASSWORD = 유저 비밀번호

config.js 파일에 적용합니다.

import 'dotenv/config';
const env = process.env;

export default {
  development: {
    host: env.DB_HOST,
    port: env.DB_PORT,
    database: env.DB_DB,
    username: env.DB_USER,
    password: env.DB_PASSWD,
    dialect: 'mysql',  	// 사용하는 DB 종류
  },
  test: {
    host: env.DB_HOST,
    port: env.DB_PORT,
    database: env.DB_DB,
    username: env.DB_USER,
    password: env.DB_PASSWD,
    dialect: 'mysql',
  },
  production: {
    host: env.DB_HOST,
    port: env.DB_PORT,
    database: env.DB_DB,
    username: env.DB_USER,
    password: env.DB_PASSWD,
    dialect: 'mysql',
  },
};

폴더 구조 변경

sequelize init 이후 네 개의 폴더가 루트에 있습니다. 모두 데이터베이스를 위한 폴더임을 알고 있으니까 db 폴더에 넣어서 정리하도록 하겠습니다.

.     
|-- db
|	|-- config
|   |	`-- config.json
|	|-- migrations     
|	|-- models
|  	|	`-- index.js    
|	|-- seeders   

sequelize 명령어는 초기화가 완료된 후 4개의 폴더가 있다는 것을 가정하고 명령을 수행하게 됩니다. 그래서 폴더들이 있는 경로에서 명령을 해야하는데, 매번 db 폴더로 경로 이동하는 건 번거롭기도 하죠? 아래 파일을 생성해서 시퀄라이즈에게 너가 찾는 파일이 여기에 있다고 알려줍니다.

import { resolve } from 'path';

export default {
  config: path.resolve('config', 'config.js'),
  'models-path': resolve('db', 'models'),
  'seeders-path': resolve('db', 'seeders'),
  'migrations-path': resolve('db', 'migrations'),
};

index.js 탐구

models 폴더의 index.js 파일은 관계형 데이터베이스와 작성한 모델들을 매핑해주는 기능을 해서 ORM의 코어역할을 수행합니다.

우선 모듈 임포트하는 부분에서 config 경로를 변경합니다. .json -> .js

import config from '../config/config.js';

매핑은 다음의 과정으로 이루어집니다. 순서가 뒤바뀌면 제대로 실행되지 않으니 순서를 꼭 기억해 주세요!

1. db 객체 생성

const db = {};

2. 시퀄라이즈와 DB를 연결
config 객체(개발, 테스트, 배포)에 따라 데이터베이스 정보를 가지고 온 뒤 Sequelize()로 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);
}

저는 편의에 따라 아래처럼 바꿨습니다.

let sequelize = new Sequelize(
  config[env].database,
  config[env].user,
  config[env].password,
  config[env]
);

3. 모델이 작성된 파일을 찾아 db 객체에 삽입

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

4. 모델 간 관계 설정

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

저는 편의에 따라 아래처럼 바꿨습니다.2222

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

5. db 객체에 시퀄라이즈 삽입 및 export

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

export default db;

이렇게 만들어진 db 객체는 앞으로 데이터베이스에 접근해 해당 모델의 데이터를 가져오고 변경하는데 쓰이게 됩니다. 쿼리문 없이 자바스크립트만으로 데이터베이스와 상호작용 할 수 있게 되는 것이죠.

서버와 연결

마지막으로 db 객체를 서버와 연결하면 모든 설정이 완료됩니다!

import db from '../db/models';

db.sequelize
  .sync({ force: false })
  .then(() => {
    console.log('✅ DB Connected!');
  })
  .catch((err) => {
    console.error(err);
  });

시퀄라이즈는 nodejs를 위한 비동기 처리를 지원한다는 것도 코드를 통해 확인할 수 있습니다.

정리

시퀄라이즈를 처음 적용해 보는 거라 실수도 하면서 시간을 들이게 됐습니다. 개발도 전에 환경구축 하느라 시간 많이 쓰면,, 힘.. 빠지잖아요☺️ 이 포스팅 보시는 분들 모두 한 번만에 설정 끝내시구 즐거운 개발 시작하시길 바라겠습니다!

profile
Want to be backend developer

0개의 댓글