본문 바로가기

Node.js

[Node.js] SQLite 데이터를 MariaDB로 마이그레이션하기

SQLite 데이터베이스 파일을 읽기 위한 sqlite3 모듈 설치

sqlite 데이터를 조회해 오는 코드 작성

 

 

조회한 데이터를 마리아디비로 마이그레이션하기 위해 mysql2 모듈 설치

 

데이터베이스 연결 모듈 

 

sqlite조회하고 mariadb 에 마이그레이션 (sqlite테이블 스키마 조회, mariadb 테이블생성, sqlite 데이터 조회, mariadb 데이터 삽입 모듈로 분리 예정)

 

 

const express = require("express");
const router = express.Router();
const sqlite3 = require("sqlite3").verbose(); // verbose() 메서드를 사용하여 더 많은 디버깅 정보 출력
const mysql = require("mysql2/promise");

// SQLite 데이터베이스 파일 경로
const dbFilePath = "./orgchart.sqlite";

// SQLite 데이터베이스 연결
const sqliteDB = new sqlite3.Database(dbFilePath);

// MariaDB 연결 설정
const mariaDBConfig = {
  host: "127.0.0.1",
  user: "root",
  password: "maria",
  database: "sky",
  dialect: "mysql",
};

// MariaDB 연결
async function connectToMariaDB() {
  try {
    const connection = await mysql.createConnection(mariaDBConfig);
    console.log("MariaDB 연결 확인");
    return connection;
  } catch (error) {
    console.error("MariaDB 연결 오류:", error);
    return null;
  }
}

// SQLite 테이블 스키마(테이블 구조 및 정의) 조회
async function getTableSchema(tableName) {
  return new Promise((resolve, reject) => { // 새로운 프로미스 생성
    sqliteDB.get( // SQLite 데이터베이스에서 테이블 스키마 조회
      `SELECT sql FROM sqlite_master WHERE name = ?`, // 주어진 테이블 이름에 해당하는 테이블 스키마 조회
      [tableName], // 테이블 이름을 파라미터로 전달
      (err, row) => { // row: 조회 결과
        if (err) {
          reject(err);
        } else {
          resolve(row.sql); // row.sql: 테이블 스키마 정보 반환
        }
      }
    );
  });
}

// 테이블 생성 및 데이터 삽입
sqliteDB.all(
  "SELECT name FROM sqlite_master WHERE type='table'", // 테이블 목록 조회
  async (err, tables) => {
    if (err) {
      console.error(err.message);
      return;
    }

    console.log("테이블 목록:");

    // 배열을 사용하여 모든 데이터 삽입 작업이 완료될 때까지 기다리기 위한 프로미스 배열 생성
    const insertPromises = [];

    for (const table of tables) { // tables: 테이블 목록, 각 요소를 순서대로 table 변수에 할당
      const tableName = table.name;

      // SQLite DB에 있는 테이블 스키마 조회
      const tableSchema = await getTableSchema(tableName);

      if (tableSchema) {
        // MariaDB 연결 설정
        const mariaDBConnection = await connectToMariaDB();

        if (mariaDBConnection) {
          // MariaDB에 테이블 생성
          const createTableQuery = tableSchema.replace(
            // SQLite 테이블 스키마에서 AUTOINCREMENT를 AUTO_INCREMENT로 변경, /g플래그: 전역 검색
            // SQLite 테이블 스키마에서는 AUTOINCREMENT를 사용, MriaDB에서는 AUTO_INCREMENT를 사용하기 때문에 필요함
            /AUTOINCREMENT/g,
            "AUTO_INCREMENT"
          );
          try {
            await mariaDBConnection.execute(createTableQuery);
            console.log(`테이블 생성 완료: ${tableName}`);

            // 데이터 조회 쿼리 생성
            const selectQuery = `SELECT * FROM ${tableName}`;
            console.log(`데이터 조회 쿼리: ${selectQuery}`);

            // 데이터 조회
            const rows = await new Promise((resolve, reject) => {
              sqliteDB.all(selectQuery, (err, rows) => {
                if (err) {
                  reject(err);
                } else {
                  resolve(rows);
                }
              });
            });

            // MariaDB에 데이터 삽입
            const insertPromise = (async () => {
              for (const row of rows) { // rows: 데이터 조회 결과, 각 요소를 순서대로 row 변수에 할당
                const columnNames = Object.keys(row); // 현재 row의 속성 이름을 배열로 저장
                const insertQuery = `INSERT INTO ${tableName} (${columnNames.join(
                  ", "
                )}) VALUES (${columnNames.map(() => "?").join(", ")})`;
                const values = columnNames.map((columnName) => row[columnName]); // coloumnNames 배열의 각 요소에 대해 row[columnName]을 실행하여 배열 생성

                try {
                  const [result] = await mariaDBConnection.execute(
                    insertQuery,
                    values
                  );
                  console.log(`데이터 삽입 결과:`, result);
                } catch (error) {
                  console.error(`데이터 삽입 중 오류:`, error);
                }
              }

              // MariaDB 연결 닫기
              mariaDBConnection.end();
            })();

            insertPromises.push(insertPromise);
          } catch (error) {
            console.error(`테이블 생성 중 오류:`, error);
          }
        }
      }
    }

    // 모든 데이터 삽입 작업을 기다리기
    await Promise.all(insertPromises);

    // SQLite 데이터베이스 연결 닫기
    sqliteDB.close((err) => {
      if (err) {
        console.error(err.message);
      }
      console.log("SQLite 데이터베이스 연결이 닫혔습니다.");
    });
  }
);

module.exports = router;