즐코

Sequelize - 시퀄라이즈 기본 (모델 정의 및 옵션 설정) 본문

mySQL

Sequelize - 시퀄라이즈 기본 (모델 정의 및 옵션 설정)

YJLEE_KR 2022. 5. 15. 20:00

시퀄라이즈란?

 

ORM 도구이다. mysql과 같은 DB 작업을 쉽게 할 수 있도록 도와주는 라이브러리이다.

 

여기서 ORM 이란 뭘까?

ORM : Object-Relational Mapping : 자바스크립트 객체와 관계형 데이터인 DB를 매핑해주는 도구

쉽게 말하자면, 자바스크립트 구문을 알아서 sql로 번역해준다. 

Mysql 뿐만 아니라 MariaDB, PostgreSQL 등 다양한 데이터베이스를 쓸 수 있게 해준다.

 

 

1/ 시퀄라이즈에 필요한 패키지 설치 및 기본 세팅

 

sequelize-cli : 시퀄라이즈 명령어 실행을 위한 패키지

mysql2 : mysql과 시퀄라이즈를 이어주는 드라이버

 

npm install sequelize sequelize-cli mysql2
// 설치 완료 후 
npx sequelize init

 

npx sequelize init 하면 자동으로 config(config.json), migrations, models, seeders 가 생긴다.

- config : DB 연결 정보 저장

- migration : 마이그레이션에 필요한 데이터가 자동으로 저장되는 디렉토리

- models : DB 테이블 저장, 해당 디렉토리 상에 각 테이블별 파일을 저장한다

- seeders : 테스트에 필요한 데이터를 정의 

 

 

models/index.js 수정 

: 자동생성되면서 생긴 코드 중에 필요없는 코드는 지우고 아래와 같이 수정해줌

 

Sequelize : 시퀄라이즈 패키지, 생성자

config/config.json에서 DB 설정을 불러온 다음에, new Sequelize를 통해 MySQL 연결 객체를 생성

 

'use strict';

const Sequelize = require('sequelize');
const env = process.env.NODE_ENV || 'development';
const config = require(__dirname + '/../config/config.json')[env];

// mysql 연결 객체 만들어주기
const sequelize = new Sequelize(config.database, config.username, config.password, config);

const db = {};
// 연결 객체 재사용을 위해 db객체에 넣어주기
db.sequelize = sequelize;
db.Sequelize = Sequelize;

module.exports = db;

 

config/config.json 수정

: development, test, production mode별로 서로 다른 DB를 사용할 수 있게끔 도와준다.

우선, process.env.NODE_ENV 가 기본적으로 development로 되어 있으므로 development 쪽만 건드려준다.

추후 배포할 때 process.env.NODE_ENV 를 production으로 설정하면 된다.  

 

// 우선 development용으로만 내 db 계정 정보 저장
{
  "development": {
    "username": "yjlee",
    "password": "1234",
    "database": "test_sequelize",
    "host": "127.0.0.1",
    "dialect": "mysql"
  },

 

2. 시퀄라이즈 통해서 express서버와 mysql 연결하기 

 

server.js 

: models에서 sequelize 객체를 가져와서 서버와 연결해주는 작업을 해주자.

sequelize 메서드 sync 로 서버 실행 시 db와 연동되어 자바스크립트 모델과 db가 동기화 할 수 있게 해준다. 

const { sequelize } = require('./models')

sequelize.sync({ force: false })
  .then(() => {
    console.log('DB 연결 성공!')
  }).catch((err) => {
    console.log(err)
  })

서버가 돌아가는 시점에 동기화를 해주고 싶다면, 아래와 같이 작성해도 되겠다.

// server.js

httpServer.listen(4000, async () => {
    try {
    	await sequelize.sync({ alter: true });
        console.log("server is running");
        console.log("DB sync!");
    } catch (err) {
    	console.log(err);
    }
});

 

sync 옵션엔 대표적으로 force, alter가 있다.

 

- sync의 force 옵션 

true로 설정 시 : 모델 수정 시 db에 반영, 서버 실행시마다 기존 테이블을 삭제하고 재생성해준다.

기존에 있던 테이블의 내용이 아닌 칼럼이 바뀔 경우엔 force : true 옵션을 써서 이전 테이블을 삭제하고 재생성해주는 것도 괜찮을 듯

 

- sync의 alter 옵션

true로 설정 시 : 새로운 테이블이 생겼을 경우 사용, alter로 하면 기존 db 데이터가 날라가지 않는다. 

 

이제, 터미널 상에 npm start로 서버 실행하고 error 메시지가 안뜨면 연결 성공!

(npm start 전에 config.json 상에 넣어둔 database가 실제 db 상에 없으면 에러가 뜨니 미리 database 생성해두기)

  

 

3. 모델 정의하기

 

models 디렉토리 안에 만들고자 하는 table 별로 파일들을 생성해주면 된다.

모델 생성하는 방법은 간단하다. sequelize, Sequelize.DataTypes를 인자로 받아와서 sequelize.define 함수를 사용하여 생성한다.

 

sequelize.define(3가지 파라미터)

1. db에 만들고자하는 테이블명 

2. 테이블 내의 각 칼럼별 정의

3. 테이블 옵션 설정

 

models/user.js 

: Users 라는 테이블을 생성

 

module.exports = (sequelize, DataTypes) => {
  const User = sequelize.define('User', {
    _id: {
      type: DataTypes.INTEGER,
      autoIncrement: true,
      primaryKey: true,
    },
    email: {
      type: DataTypes.STRING(64),
      allowNull: false,
    },
    password: {
      type: DataTypes.STRING(64),
      allowNull: false,
    },
    provider: {
      type: DataTypes.STRING(8),
      defaultValue: 'local'
    },
    point: {
      type: DataTypes.INTEGER,
      defaultValue: 0
    }
  }, {
    timestamps: false,
    paranoid: false,
    tableName: 'user',
    charset: 'utf8mb4',
    collate: 'utf8mb4_general_ci'
  })

  return User;
}

 

1/ 첫번째 파라미터 : 모델 (테이블) 명 설정

 

시퀄라이즈는 기본적으로 모델명을 단수로 이해하고 테이블명은 복수로 다룬다. 

즉, 테이블명을 설정하는 첫번째 파라미터로 'User'라고 정의해도,

세번째 파라미터에 옵션을 더해주지 않는 이상 'User' 대신 'users' 라는 테이블이 생성된다.

 

- 모델명과 다르게 테이블 이름을 내 임의대로 지정해주고 싶다면, 세번째 파라미터로 아래 옵션을 추가해주자

 tableName : '내가 설정하고픈 테이블명'

- 복수처리하고싶지않고 테이블명을 모델명과 통일하고 싶다면, 아래 옵션 추가해주기 

freezeTableName : true 

 

 

2/ 두번째 파라미터 : 칼럼 정의 

 

스키마를 정의해주는 부분이다. 대표적으로 많이 넣는 속성들은 아래와 같다. 

데이터 유효성 검사도 해줄 수 있는 옵션도 있다!

 

type 데이터 타입, 자료형 정의 (type : Datatypes.데이터타입) *데이터 타입은 아래 표 참고
primaryKey 기본키 설정 (primaryKey : true)
autoIncrement 숫자 자동 증가 (autoIncrement : true)
allowNull NOT NULL 설정 (allowNull : false)
unique UNIQUE 설정 (unique : true)
defaultValue 디폴트값 설정 (defaultValue : 기본으로 설정해주고자 하는 값)
디폴트값을 now() 로 설정하고 싶을 경우엔 좀 특이해서 기록해둔다. 
defaultValue : Sequelize.NOW 라고 추가해주면 된다. 
comment 각 칼럼에 대한 설명 : 이 옵션엔 logical name을 넣어주면 좋을듯! (comment: 사용자 고유번호 )
validate 데이터 유효성 검사를 해주는 속성
validate : {
  isEmail : true, (이메일형식 검사)
  또는, is : /^[a-z]+$/i, (내가 원하는 포맷이 있다면 정규식표현 넣어주기) 
}

 

데이터 타입명이 mysql 과 살짝 다르다. 많이 쓰는 것들만 정리해보면 아래와 같다.

 

mysql 자료형 표현 sequelize 자료형 표현
VARCHAR(255) STRING(255)
INT INTEGER
TINYINT BOOLEAN
DATETIME DATE

 

3/ 세번째 파라미터 : 테이블 자체의 옵션 설정

 

timestamps 기본 설정은 true이다. true로 설정 시, createdAt, updatedAt이라는 칼럼이 자동으로 생성된다. 
말그대로 데이터가 생성되는 시간, 업뎃되는 시간을 남겨준다. 
false로 설정하면 생성되지 않는다. 만약, 둘 중 하나만 남기고 싶다면, 
{ timestamps : true, createdAt : true, updatedAt : false } 로 한다면 생성시간 칼럼만 생성된다. 
paranoid true로 설정 시, deleteAt이라는 칼럼이 추가된다.
데이터 삭제 요청 쿼리가 들어왔을때, 해당 데이터를 삭제하지 않고 삭제되는 시점을 등록해둔다고 한다. 
백업 서버나 데이터 복구를 쉽게하기 위해서 쓴다고 한다. 
대신 timestamps : true 로 설정해놔야 쓸 수 있는 옵션이다. 
underscrored 시퀄라이즈는 기본적으로 테이블명, 칼럼명을 camel case로 만든다.
이 옵션을 true 로 해두면 snake case로 바꿔주는데, 필요할 때 쓰면 될듯하다
tableName 위에서 설명한대로 테이블명을 시퀄라이즈가 설정하는대로가 아닌 내 임의대로 설정하고플 때 사용
freezeTableName 시퀄라이즈의 모델명과 테이블명을 통일하고싶을 때 사용
charset
collate
각각 utf8, utf8_general_ci 로 설정해야 한글 입력이 가능하다. 이모티콘 입력까지 하고싶으면 아래처럼 설정하기
charset: 'utf8mb4',
collate: 'utf8mb4_general_ci' 

 

4. 모델 정의 후 db 객체에 추가해주기

 

models/index.js

 

'use strict';

const Sequelize = require('sequelize');
const env = process.env.NODE_ENV || 'development';
const config = require(__dirname + '/../config/config.json')[env];
const sequelize = new Sequelize(config.database, config.username, config.password, config);
// User 모델 끌어오기
const User = require('./user')(sequelize, Sequelize.DataTypes)

const db = {};
db.sequelize = sequelize;
db.Sequelize = Sequelize;
db.User = User; // User 모델(테이블) 추가 

module.exports = db;

 

user 테이블이 설정한대로 생성되었다! 

 

 

추가 tip!

 

시퀄라이즈를 사용하다보면, 아래와 같이 콘솔창에 굉장히 많은 sql 쿼리 로그가 찍힌다. 이게 처음에는 괜찮은데, 시퀄라이즈 구문이 많아지면 콘솔창이 굉장히 지저분해지고 sql 외의 다른 로그를 찍게 될 때 찾을 수 없을만큼.. 불편해진다. 

따라서, 이 로그 기능을 막으려면 sequelize 인스턴스 생성 시 logging 옵션을 추가해줘야 한다.

// db/models/index.js

const options = {
  logging: false,
};

const sequelize = new Sequelize(
  config.database,
  config.username,
  config.password,
  config,
  options
);

 

또는, 특정 쿼리만 log되지 않게 막을 수 있다! 

로그되지 않으면 하는 특정 시퀄라이즈 구문에 logging: false 옵션을 넣어주는 방식이다. 

const User = require('../models/user')

const user = await User.findOne({  
  logging: false,
  where: { id: 2207 }
})
Comments