엘리스 AI트랙 4기/프로젝트

[Typescript Express] Sequelize로 MySQL 연결하기

남쪽마을밤송이 2022. 6. 8. 21:55

 [01 Typescript란? ] 

  • TypeScript는 JavaScript 기반의 언어이다.
  • JavaScript는 클라이언트 측 스크립팅 언어지만 TypeScript는 객체 지향 컴파일 언어이다.
  • TypeScript는 JavaScript의 상위 집합으로 JavaScript의 모든 기능이 있다.
  • 클래스 기반이므로 객체 지향 프로그래밍 언어로 상속, 캡슐화 및 생성자를 지원할 수 있다.
  • TypeScript는 그 자체로 실행이 안 되고 Javascript로 컴파일러를 사용하여 ts(TypeScript)파일을 js(JavaScript) 파일로 변환한다. 그래서 얼핏 보면 그렇게까지? 성능 더 떨어지는거 아니야? 할 수 있는데 현업에서는 엄청 많은 양의 코드를 다루다 보니 타입 미지정으로 인한 이슈가 크기 때문에 필수라고 한다.

  • 나와 우리 팀원은 TypeScript는 JavaScript와 비슷하고, MySQL은 기본적인 쿼리는 다 알고 있음 + Mongoose와 비슷하겠지 하는 생각으로 쉽게 접근했는데 각각 회원 가입과 로그인을 이틀동안 구현하면서 진심으로 현타와서 눈물날 뻔 했다.
  • 5주짜리 프로젝트라서 기술 스택을 바꾼거기도 하지만 그래도 시간의 압박이 있으니 괜히 바꿨나 후회도 했는데... 그래도 해결한 걸 기록하고 성장하면서 적응할 거라고 믿는다 아자!🤣

 [02 Sequelize 초기 세팅 ] 

  • 먼저 패키지 매니저로 sequelize와 mysql을 설치한다.
  • npm i -D sequelize-cli 로 sequelize-cli 모듈을 설치한다.
  • 원하는 경로에서(db 폴더) npx sequelize init을 실행해 sequelize 초기 구조를 세팅한다. (아래의 폴더와 파일들이 자동으로 생성됨)

 (1) config.ts 파일 

  • 이 때 config/config.json 파일이 생성될텐데 TypeScript는 이를 config.ts 파일로 바꿔줘야 한다.
  • 아래와 같이 dotenv 파일을 이용하여 본인의 계정정보와 사용할 DB 종류를 넣은 config 파일을 설정해준다.
    • dotenv 파일은 당연히 .gitignore 파일에 들어가야 한다!
import dotenv from "dotenv";
dotenv.config();

const config = {
  development : {
      username : process.env.DB_USERNAME || 'root',
      password : process.env.DB_PASSWD,
      database : process.env.DB_DBNAME || 'test',
      host : process.env.DB_HOST || 'localhost',
      dialect : "mysql"
  }
};

export default config;

 (2) index.ts 파일

  • 다음은 models/index.ts 파일에서 config 파일 정보를 이용해 sequelize 연결 정보를 생성해준다.
import { Sequelize } from "sequelize";
import config from "../config/config";

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

export default sequelize;

+) 2022.06.13

  • 위와 같이 설정해주었더니 ubuntu에서 MySQL 서버 timezone을 한국 시간대로 바꿨음에도 불구하고 DB에 모든 시간이 UTC로 저장되는 문제를 겪었다.
  • 구글링을 통해 그럴 경우 sequelize 연결 객체를 생성할 때 다음과 같이 옵션을 추가해줘야 한다는 사실을 알게 되었다.
const sequelize = new Sequelize(config.development.database, config.development.username, config.development.password, {
  host: config.development.host,
  dialect: "mysql",
  timezone: "+09:00",
  dialectOptions: { charset: "utf8mb4", dateStrings: true, typeCast: true },
  define: {
    timestamps: true,
  },
});
  • 더보기
    그런데 사실 또 한 건 해결했다고 생각한 순간 코치님께서 DB에는 UTC로 저장하고 불러올 때 시간을 변환하는 걸 추천한다고 말씀해주셨다😂 알겠습니다! 했지만 속으로는 헉...왜지?! 매 번 불편하지 않나?? 했는데 캘린더 기능으로 인해 계속 Datetime Type을 사용할 일이 많아지면서 response로는 UTC 시간이 그대로 출력돼 헷갈린다던가 시간 입력 없이 new Date("2022-06-13")을 저장하게 되면 무조건 +09:00 하는 옵션 때문에 2022-06-13 09:00:00로 들어가는 문제 등이 왜 UTC로 저장하라고 하셨는지 깨닫게 했다...😌

 (3) index.ts 파일 

  • 마지막으로 back/index.ts 파일에서(listen 함수가 있는 파일) authenticate 메소드를 추가해 연결을 확인한다. 
import app from "./src/app";
import { sequelize } from "./src/db/models/index";

import { createServer } from "http";

const port: number = Number(process.env.PORT) || 5001;

const server = createServer(app);

server.listen(port, async () => {
  console.log(`정상적으로 서버를 시작하였습니다.  http://localhost:${port}`);

  // authenticate 메소드로 연결 확인
  await sequelize
    .authenticate()
    .then(async () => {
      console.log("connection success");
    })
    .catch((e: Error) => {
      console.log(e);
    });
});

export default server;
  • 정상적으로 서버를 시작했다면 설정한대로 다음과 같은 메세지를 확인할 수 있다.