MongoDB에서 MySQL로 데이터 이전 with csv

MongoDB에서 MySQL로 데이터 이전 with csv

Express.js와 MongoDB를 이용하여 작성했던 게시판 프로젝트가 있다. 헤로쿠가 무료 플랜을 중단하면서 서버가 내려갔었는데, 친구들의 요청이 있기도 했고 NestJS와 MySQL + kysely를 손에 익힐 겸 다시 재작성하고 있다.

프로젝트를 살리는 김에 이전 글들을 볼 수 있으면 좋을 것 같다는 생각이 들었다.

그러니 알아보자. MongoDB의 데이터를 MySQL로 이전하는 방법

MongoDB에서 데이터 추출

mongoexport 명령어를 이용하면 저장된 데이터를 csv 형식이나 json 형식의 파일로 가져올 수 있다. (참고: MongoDB Documentation)

나는 uri를 이용한 방법으로 진행했다. 인스턴스의 uri와 액세스 권한이 있는 유저의 이름과 비밀번호를 확인하여 아래 명령어를 입력한다.

mongoexport --uri mongodb+srv://<유저명>:<비밀번호>@<호스트> --type csv -c <컬렉션명> -f <콤마로구분한필드명> -o <파일명.csv>

이렇게 하면 해당 컬렉션의 데이터를 csv 파일 형태로 가져올 수 있다.

MySQL에 csv 파일 덤프

LOAD DATA INFILE 명령어를 이용하여 csv 파일을 import해보자. (참고: MySQL LOAD DATA Statement)

파일을 가져올 수 있는 위치는 기본적으로 제한되어 있다. secure_file_priv 옵션을 확인해보자.

show variables like "secure_file_priv";

import할 파일이 해당 위치에 있어야 한다는 뜻이다. 현재 저 DB는 도커에서 돌아가고 있기 때문에 로컬 위치를 의미하지 않는다. 로컬 파일을 이용하여 데이터를 가져올 수도 있지만 기본적으로 local_infile 옵션은 off로 설정되어 있기 때문에 해당 옵션을 변경하기 보다는 csv 파일을 도커로 전송하여 사용해보도록 하자. (local_infile 옵션을 true로 설정한 후 LOAD DATA LOCAL INFILE 명령어를 이용하면 로컬 파일 사용 가능)

로컬 파일을 도커로 전송하려면 docker cp 명령어를 이용하면 된다.

docker cp [파일위치] [컨테이너 이름]:/var/lib/mysql-files

이렇게 하면 csv 파일이 도커로 전송된 것을 확인할 수 있다.

이제 전송한 파일을 이용하여 데이터를 입력해 보자.

LOAD DATA INFILE '/var/lib/mysql-files/post.v1.csv'
INTO TABLE post
FIELDS
    terminated by ',' -- csv 구분자
    optionally ENCLOSED by '"'
ignore 1 lines -- csv 파일 헤더 무시
(@title, content, name, file_url, @views, @date_time) -- @로 지정하면 변수로 받음
SET
    created_at = STR_TO_DATE(@date_time, '%Y-%m-%dT%H:%i:%s.%fZ'),
    views = 0, -- 해당 csv 파일엔 조회수가 존재하지 않아서 기본값 설정
    uid = null,
    title = LEFT(@title,100); -- mongodb에 저장된 글 중 제목 길이가 100글자 이상인 글 처리

데이터가 post 테이블에 잘 입력된 것을 확인할 수 있다.