그누보드7 데이터를 WordPress WXR로 변환하는 방법: 대량 게시글 이전에 적합한 이유
그누보드7에서 WordPress로 사이트를 이전할 때 가장 큰 고민은 게시글만 옮기는 것이 아니라 댓글, 카테고리, 작성일, 첨부파일 등 기존 데이터를 얼마나 온전하게 유지할 수 있느냐는 점이다. 게시글이 수백 건 수준이라면 직접 복사하거나 API를 이용하는 방법도 가능하지만, 수천 건 이상의 데이터를 이전해야 한다면 처리 속도와 안정성이 중요한 기준이 된다.
이 글에서는 그누보드7 데이터를 WordPress에서 지원하는 WXR(WordPress eXtended RSS) 형식으로 변환하는 구조와 구현 방법, 그리고 실제 구현 과정에서 고려했던 설계 방향을 소개한다.
왜 WXR 방식을 선택했을까?
WordPress는 자체 Import 기능을 통해 WXR(XML) 파일을 가져올 수 있다. WXR은 단순한 XML 문서가 아니라 WordPress가 이해하는 데이터 교환 포맷으로, 게시글뿐 아니라 카테고리, 작성자, 댓글, 메타데이터까지 함께 포함할 수 있다.
즉, 단순히 데이터베이스 내용을 내보내는 것이 아니라 WordPress가 그대로 복원할 수 있는 형태로 변환하는 것이 핵심이다.
구현 과정에서는 다음 세 가지 원칙을 중심으로 설계를 진행했다.
- 게시판을 WordPress 카테고리로 매핑한다.
- 게시글과 댓글 구조를 그대로 유지한다.
- 첨부파일은 메타데이터 형태로 기록한다.
첨부파일까지 WordPress Media Library에 자동 등록하는 방식도 고려할 수 있지만, 대량 이전에서는 네트워크 오류나 업로드 실패 가능성이 높아진다. 따라서 우선 파일 경로와 메타데이터만 함께 저장하고, 이후 별도 스크립트로 실제 파일을 연결하는 방식이 더 안정적이었다.
REST API보다 WXR이 유리한 이유
WordPress REST API를 이용하면 게시글을 하나씩 생성할 수 있다. 구현 자체는 직관적이지만 대량 이전에서는 단점이 분명하다.
예를 들어 게시글이 8,000개라면 최소 8,000회의 API 요청이 발생한다. 여기에 댓글이나 첨부파일까지 포함하면 요청 수는 훨씬 많아진다.
또한 다음과 같은 문제가 생길 수 있다.
- API 속도 제한
- 인증 토큰 만료
- 네트워크 오류
- 중간 실패 시 재시도 처리
반면 WXR 방식은 XML 파일 하나만 생성하면 WordPress Import 기능이 전체 데이터를 한 번에 처리한다. 게시글 수가 많을수록 관리가 쉬워지고 실패 가능성도 줄어든다.
실제로 게시글이 5,000건 이상인 환경이라면 WXR 방식이 훨씬 안정적인 선택이다.
게시판 선택과 데이터 조회 구조
변환 스크립트는 URL 파라미터를 기준으로 내보낼 게시판을 결정한다.
지원하는 형태는 다음과 같다.
- 특정 게시판 슬러그
- 게시판 ID
- 전체 게시판
입력값에 따라 조회 조건을 변경한 뒤 대상 게시판 목록을 가져오고, 이후 각 게시판을 순회하면서 게시글과 댓글을 수집하는 구조다.
데이터베이스 연결은 .env 파일의 환경 변수를 이용하도록 구성했다. 데이터베이스 접속 정보를 코드에 직접 작성하지 않기 때문에 운영 환경과 개발 환경을 쉽게 분리할 수 있고, 배포 과정에서도 별도의 코드 수정이 필요하지 않다.
PDO를 사용한 이유 역시 명확하다.
- Prepared Statement 지원
- 예외 기반 오류 처리
- 다양한 DB 환경과의 호환성
게시판 조회 단계에서는 is_active = 1 조건을 적용해 비활성 게시판을 제외했으며, 게시글은 depth = 0 조건을 이용해 원글만 가져오도록 구성했다. 댓글은 게시글 ID를 기준으로 별도 조회해 연결한다.
Markdown과 HTML을 함께 처리하는 콘텐츠 변환
그누보드7에서는 게시글 저장 방식이 하나로 고정되어 있지 않을 수 있다.
일부 게시글은 HTML이고, 일부는 Markdown일 수도 있다.
이를 처리하기 위해 콘텐츠의 저장 형식을 먼저 확인한 뒤 변환 방식을 결정했다.
Markdown인 경우에는 HTML로 변환한 후 WXR에 저장한다.
가능하다면 Parsedown 라이브러리를 이용해 변환하고, 라이브러리가 없는 환경에서는 기본적인 Markdown 문법만 처리하는 최소 변환 로직을 사용하도록 설계했다.
이러한 방식은 추가 라이브러리를 설치할 수 없는 서버에서도 동일한 스크립트를 사용할 수 있다는 장점이 있다.
댓글 구조도 그대로 유지해야 한다
게시글 이전보다 어려운 부분은 댓글이다.
댓글은 단순 목록이 아니라 부모 댓글과 답글 관계까지 유지해야 한다.
이를 위해 댓글의 parent_id 값을 함께 조회하고, WXR의 wp:comment_parent 요소에 기록하도록 구현했다.
또한 댓글 존재 여부에 따라 WordPress의 댓글 허용 상태도 함께 설정했다.
- 댓글이 없으면
comment_status = closed - 댓글이 하나 이상 있으면
comment_status = open
이 설정은 Import 이후 댓글 기능이 정상적으로 유지되는 데 영향을 준다.
메모리를 아끼는 XML 생성 방식
대량 데이터를 XML로 생성할 때 흔히 사용하는 방법은 모든 데이터를 배열에 저장한 뒤 한 번에 출력하는 것이다.
하지만 게시글 수가 많아질수록 메모리 사용량도 함께 증가한다.
이를 피하기 위해 XML은 출력 버퍼를 사용하지 않고 스트리밍 방식으로 생성했다.
RSS 구조를 순차적으로 출력하면서 게시글마다 <item> 요소를 생성하기 때문에 메모리 사용량을 크게 줄일 수 있다.
실제 테스트에서는 게시글 약 8,000건 기준 XML 생성 시간이 약 3.2초 수준이었다. 대부분의 시간은 데이터베이스 조회에 사용됐으며, XML 자체를 생성하는 작업은 상대적으로 빠르게 처리됐다.
게시판과 첨부파일은 어떻게 매핑했을까?
게시판은 WordPress의 카테고리로 변환했다.
각 게시글에는 해당 카테고리를 연결해 기존 게시판 구조를 그대로 유지하도록 구성했다.
첨부파일은 조금 다른 접근을 선택했다.
WordPress의 Attachment Post를 생성하는 대신 첨부파일 정보를 JSON 형태의 Post Meta로 저장했다.
여기에는 다음과 같은 정보가 포함된다.
- 원본 파일명
- 저장 경로
- MIME 타입
- 파일 크기
- 이미지 여부
- 추가 메타데이터
이미지인 경우에는 썸네일 경로도 함께 저장해 이후 별도 스크립트에서 WordPress Media Library와 연결할 수 있도록 설계했다.
이 방식은 Import 과정의 부담을 줄이면서도 원본 파일 정보를 잃지 않는 현실적인 절충안이다.
작성자 정보는 왜 하나로 통합했을까?
사용자 계정까지 완전히 이전하려면 WordPress 사용자와 기존 회원 정보를 일대일로 매핑해야 한다.
하지만 계정 중복이나 권한 충돌, 이메일 중복 등 다양한 문제가 발생할 수 있다.
그래서 기본 구현에서는 하나의 작성자로 통합하고, 작성자 이름만 게시글에 유지하도록 구성했다.
만약 여러 작성자의 계정을 그대로 유지해야 하는 프로젝트라면 별도의 사용자 매핑 테이블과 계정 생성 절차를 추가하는 것이 바람직하다.
이 방식의 한계와 확장 가능성
현재 구조는 게시글과 댓글을 안정적으로 이전하는 데 초점을 맞추고 있다.
반면 다음과 같은 기능은 별도 구현이 필요하다.
- WordPress Media Library 자동 등록
- 사용자 계정 자동 매핑
- 복잡한 카테고리 계층 구조 변환
특히 첨부파일은 경로 정보만 저장되므로 실제 파일은 별도로 업로드하거나 후처리 스크립트를 통해 Attachment로 등록해야 한다.
또한 현재는 게시판 하나를 WordPress 카테고리 하나에 대응시키는 구조다. 게시판 안에서 여러 단계의 분류 체계를 사용하는 사이트라면 카테고리 계층까지 함께 생성하는 기능을 추가하는 것이 좋다.
마무리
그누보드7에서 WordPress로 데이터를 이전하는 방법은 여러 가지가 있지만, 게시글이 많고 댓글 구조를 그대로 유지해야 하는 환경이라면 WXR 기반 변환이 가장 안정적인 선택에 가깝다.
REST API는 실시간 생성이라는 장점이 있지만 대량 데이터에서는 요청 수와 실패 가능성이 크게 증가한다. 반면 WXR은 WordPress가 공식적으로 지원하는 가져오기 형식을 활용하므로 수천 건 이상의 게시글도 비교적 안전하게 이전할 수 있다.
게시글, 댓글, 카테고리, 메타데이터를 우선 안정적으로 이전한 뒤, 첨부파일과 사용자 계정을 후처리하는 전략을 선택하면 구현 복잡도를 낮추면서도 확장 가능한 마이그레이션 환경을 구축할 수 있다.