[TypeScript] 타입스크립트로 sequelize를 활용하여 데이터베이스 연결
준비사항:
express, @types/express, mysql2, sequelize, sequelize-cli, dotenv
시작하기
sequelize init으로 config, migrations, models, seeders디렉토리를 생성한다.
이 디렉토리들을 src 디렉토리 안에 넣어도 괜찮고, 밖에 놔도 괜찮다. 자기 스타일대로 하면 된다.
나는 src 디렉토리 안으로 옮겼다.
각각 설정, 데이터베이스 관리, 모델, 초기 데이터이다.
// 터미널
sequelize init
환경변수 설정
.env 파일을 만들어주고 환경변수를 설정해 준다.(환경변수를 모르면 나중에 따로 찾아보던가 하자)
환경변수는 key=value 형식으로 작성한다.
데이터베이스 연결에 필요한 username(DB username), password(DB비밀번호), database(DB 이름), host를 설정해 주자.
dialect는 그냥 옵션이다.
.env 파일은 자동완성이 되지 않기 때문에 따로 빼두었다.
참고로 required 함수는 드림코딩 엘리님이 알려주신 꿀팁으로 알고 싶으면 돈 내고 수강하도록 하자.
dotenv에 있는 내용을 사용하려면 dotenv를 불러와서 dotenv.config()를 해주고,
process.env[환경변수]를 해주어야 한다.
더보기: 여기서 위 객체 보고 멘붕 오는 사람들을 위한 간단한 설명
여러분들이 process.env[환경변수] 할 때, 저는 config.db.환경변수 하는 거라 큰 차이 없습니다.
그냥 중간에 검사하는 단계 하나 추가된 겁니다.
결과는 process.env[환경변수]와 같습니다.
처음에 생성한 config 디렉토리 안에 있는 config.js 파일에 있는 내용을 복사한 뒤 제거해 주고, config.ts 파일을 다시 만들고 붙여 넣었다.
한 객체에 development, test, production 이 있을 텐데, 이는 각각 개발용, 테스트용, 배포용이다.
이유는 개발 to배포까지 총 세 종류의 데이터베이스를 사용하기 때문에 편의로 해놓았다고 한다.
이 파일에 dotenv를 불러오고, process.env[환경변수]를 해주면 된다.
나는 dotenv의 내용을 자동완성과 한 차례 검열을 위해 다른 ts 파일에 넣어주었다.
모델 설정
model 디렉토리로 와서 똑같이 안에 있는 index.js를 제거해 준다.
그리고 .ts 파일을 만들어 주어 sequelize와 위에서 설정해준 config.ts 파일을 불러와준다.
Sequelize는 클래스이고 첫 번째 인자부터 순서대로 데이터베이스 이름, 유저네임, 비밀번호, 옵션을 받는다.
그리고 const sequelize = new Sequelize로 새로운 객체를 하나 만들어준다.
dialect는 기본값이 mysql 이다.
먼저 interface로 해당 테이블에 있어야하는 컬럼들을 정해준다.
(컬럼이 뭔지 모르면 조용히 뒤로가기 누르고 데이터베이스 공부하고 오자)
그리고 이제 class 하나를 만들어준다. 클래스의 이름은 테이블의 이름으로 만들어주자
가장 중요한 Model을 extends 해주고 <interface>를 넣어주자.
그리고 옵션 사항이긴 한데 implements도 해주었다. (안 해도 된다.)
아!~ 또 key: type; 으로 써 넣기는 하지만, 그냥 넣으면 에러가 난다.
key와 콜론 사이에 ! 를 넣어주면된다.
우리는 Model을 상속 받아서 Motion 이라는 클래스를 만들었기 때문에 Model의 메서드를 Motion 이라는 클래스를 통해서 사용할 수 있다.
그 중 하나가 .init()이다. init 메서드는 주요한 인자 두 개를 받는다.
첫 번째 인자는 모델의 스키마를 정의하는 객체, 두 번째 인자는 모델 설정을 정의하는 객체, 그 중 하나가 모델이 사용하는 데이터베이스 연결인데 그 것이 sequelize(Sequelize의 인스턴스)이다.
지금 아래 사진의 컬럼은 id, title, body, kind 네 가지이다. 그리고 그 안에 각종 설정들이 있는데, 데이터베이스를 한 번 들여다 봤다면 알아보리라 믿는다.(안 들여다 봤다면 보고 오자)
이제 우리는 이 Motion 이라는 모델을 통해서 데이터베이스에 접근할 수 있다.
접근하는 방법은 Sequelize Model 메서드 사용방법을 참고하면 되겠다.
⚠️ 해당 게시글에는 모델을 정의하는 방법 한 가지가 더 있긴한데, 결과는 같다. 하지만 OOP(객체지향 프로그래밍)을 한다면 지금 이 방법을 추천드린다.
마이그레이션
정말 궁금했던 부분이다. 마이그레이션을 잘 하면 칭찬받는다고 했다. 난 칭찬받을래:)
마이그레이션에 대한 부분은 영상으로도 거의 없고 돈을 내고도 공부하기 참 힘들다. 그래서 이리저리 뒤져가며 공부했다.
일단 마이그레이션은 터미널로 만드는 것을 추천하는데 이유는 자동으로 생성시간을 파일 이름에 넣어서 데이터베이스 혹은 테이블의 변경 순서를 알 수 있게 해준다. (무슨 소린지 몰라도 계속 보다보면 알게된다.)
⭐️ 마이그레이션의 개념에 대해서 먼저 알고가자
마이그레이션은 파일 하나하나로 이루어져있고, 그 파일 하나하나의 이름은 변경한 기능의 이름이다.
예를 들면, 테이블을 추가하는 마이그레이션을 만들고자 한다면, 이 마이그레이션의 이름은 create_table_Motion이 될 것이다.
나중에 컬럼이 추가된다면 add_coloum_name 이런식으로 네이밍을 할 수 있다.
나는 일단 테이블을 추가하는 마이그레이션을 만들려고 한다.
npx sequelize-cli migration:generate --name 마이그레이션_이름
위와 같이 작성하면 이상한 파란생 영어가 뜨며 파일 하나가 생성된다.
그리고 확장자를 .ts로 바꿔준다.
먼저 해주어야 할 것이 있다.
import { QueryInterface, DataTypes } from 'sequelize';
그리고 저 보기싫은 에러처리 뒤에 : QueryInterface를 써준다.
그리고 Sequelize는 지워도 된다.
이제 up과 down에 대해서 설명하려고 한다.
마이그레이션은 아까 말 했다싶히 데이터베이스 버전 관리자다.
마이그레이션을 통해서 변경을 할 수 있다면, 그 것을 철회할 수도 있다.
변경하는 것을 up에, 그에 반대되는 것을 down에 넣어주어야 한다.
다음 사진을 예로 보자.
queryInterface는 저수준 데이터베이스 작업에 사용된다.
예를 들면, 테이블 생성, 삭제, 스키마 변경 등등..
일단 queryInterface.createTable로 테이블을 만들자. 첫 번째 인자는 테이블의 이름. 두 번째 인자는 컬럼 설정이다.
up은 심플하다. 테이블만 만들면 끝이다.
down을 살펴보면 조금 재밌는데, down메서드에는 그 반대인 dropTable이 있다.
이 것은 나중에 이 기능을 업데이트 했더니 문제가 생겼다거나, 이 기능을 삭제하고 싶을 때 사용된다.
사용방법은 다음과 같다.
npx sequelize-cli db:migrate:undo
위 명령어를 사용하면 가장 최근 마이그레이션에 대응하는 down을 실행한다. 딱 하나만 실행한다.
전부 초기화 하는 것도 있는데 필요하면 따로 알아보면 된다.
근데 이 쯤 되면 궁금해야할게 있는데, 얘는 뭐길래 이런걸 다 알까?
그리고 마이그레이션을 실행할 때 특정 마이그레이션을 실행하는 것이 아니라, 그냥 '마이그레이션 실행' 이라는 실행 명령어 하나만 있다.
이 것에 대한 답은 다음 사진에 있다.
짜잔~ 얘는 실행한 마이그레이션을 데이터베이스로 가지고 있다. 변태같은넘
그래서 마이그레이션을 실행하면 얘는 여기서 실행되었는지 확인하고, 실행된 것들은 넘어간다. 결국은 우리가 실행하려고 하는 마이그레이션을 실행하게 되는 것이다.
마이그레이션 실행
이제 마이그레이션을 실행하자.
npx sequelize-cli db:migrate
한 번에 성공했으면 축하하지만, 에러가 났으면 유감이다.
에러는 성공의 어머니이다.
타입스크립트를 사용한지 얼마 되지는 않았지만, 한 가지 알 수 있었다.
BABEL을 사용하지 않고, Sequelize에서 에러가 난다면... 20%는 컴파일링에서 생기는 문제이다 - -;;;
하루 만에 3개의 에러를 겪었지만 전부 컴파일링 때문에 생기는 문제였다.
Babel 씁시다.
Sequelize 설정 파일!
.sequelizerc 라는 파일이 있다. 약간 config 파일 비슷한거인데, .sequelizerc 라는 파일을 직접 만들면된다.
점 빼먹지 말자.
그리고 아래 코드를 붙여넣고 './build' 부분만 각자에 맞게 고치자.
그리고 migrations-path에 경로는 './src' 라고 되어있는데 원래는 './build'였는데 마이그레이션 파일을 생성하려고 하니 자꾸만 './build'에 있는 마이그레이션 디렉토리에 생성돼서 바꿔버렸다.
어차피 큰 프로젝트 아닌이상 빈번하게 사용하지 않을 것 같아서 그냥 필요할 때 마다 고쳐서 사용하려고 한다.
ㅠㅠ 저거 해결하는 방법 아는 사람 방법좀..
const path = require('path');
module.exports = {
config: path.resolve('./build', 'config', 'config.js'),
'models-path': path.resolve('./build', 'models'),
'seeders-path': path.resolve('./build', 'seeders'),
'migrations-path': path.resolve('./src', 'migrations'),
};
'BE > TypeScript' 카테고리의 다른 글
[OnlyForMe] TSConfig 셋업(프로젝트 구조 정리하기) (0) | 2023.06.13 |
---|---|
[TypeScript] 다양한 Utility Type이해하기 (0) | 2023.06.13 |
[TypeScript] type과 interface 차이점과 사용 팁 (0) | 2023.06.13 |
[OnlyForMe] 기본 TS 프로젝트 설정하는 방법 (0) | 2023.06.12 |
[TypeScript] abstract(추상 클래스)에 대해 이해하기 (0) | 2023.06.11 |