无需数据库服务器,如何解析SQL文件生成JSON格式数据库表?
在Node.js中无需数据库服务器直接解析SQL文件生成JSON数据
需求说明
我有一个包含创建数据库、表结构及插入数据的.sql文件,当前实现依赖MariaDB服务器,通过Node.js的mariadb模块执行SQL后导出JSON数据。现在希望完全脱离数据库服务器,直接在Node.js环境中解析SQL文件,生成对应表结构的JSON格式数据。
当前实现流程
- 准备目标.sql文件
- 利用该SQL文件在MariaDB中创建数据库并写入数据
- 通过
mariadb模块连接数据库,读取所有表数据 - 转换为JSON格式输出
现有代码示例
import mariadb from "mariadb"; // 依赖MariaDB服务器 - 希望移除该依赖 const pool = mariadb.createPool({ host, user, password, connectionLimit: 10 }); const queries = readSQLFile('./sample_sql_file.sql'); // 包含数千条SQL查询的文件 const connection = await pool.getConnection(); const dataJson = {}; // JSON格式的数据库结果 for(const query of queries) { await connection.query(query); // 执行每条SQL并保存到MariaDB } const tables = (await connection.query(`show tables in ${PROJECT_DATABASE}`)).map( (e) => e[`Tables_in_${PROJECT_DATABASE}`] ); for (const table of tables) { const data = await connection.query(`SELECT * FROM \`${table}\``); dataJson[table] = [...data]; }
期望实现流程
- 准备目标.sql文件
- 在Node.js中读取SQL文件内容
- 解析并执行所有SQL语句(内存中模拟数据库)
- 直接导出所有表的JSON格式数据
期望概念代码
import VirtualDatabase from "something"; // 无需数据库服务器的虚拟库 const queries = readSQLFile('./sample_sql_file.sql'); // 包含数千条SQL查询的文件 const dataJson = {}; // JSON格式的数据库结果 const database = new VirtualDatabase(); for(const query of queries) { database.runQuery(query); // 执行查询并生成数据库和表 } const tables = database.getTables(); // 获取数据库中所有表 for (const table of tables) { const data = database.getData(table); dataJson[table] = [...data]; }
具体实现方案
可以使用纯JavaScript实现的内存数据库库来模拟数据库环境,无需依赖外部数据库服务器。以下是两种可行方案:
方案1:使用sql.js(纯JS实现,无需编译)
sql.js是基于SQLite的纯JavaScript实现,支持在内存中创建数据库、执行SQL语句,完全符合需求。
步骤1:安装依赖
npm install sql.js
步骤2:实现代码
import fs from 'fs/promises'; import initSqlJs from 'sql.js'; async function convertSqlToJson(sqlFilePath) { // 初始化SQL.js引擎 const SQL = await initSqlJs(); // 创建内存数据库实例 const db = new SQL.Database(); // 读取SQL文件内容 const sqlContent = await fs.readFile(sqlFilePath, 'utf8'); // 批量执行所有SQL语句 db.run(sqlContent); const dataJson = {}; // 查询所有用户创建的表(排除SQLite系统表) const tablesResult = db.exec("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'"); if (tablesResult.length === 0) return dataJson; const tables = tablesResult[0].values.map(row => row[0]); // 遍历所有表,将数据转换为JSON格式 for (const table of tables) { const queryResult = db.exec(`SELECT * FROM \`${table}\``); if (queryResult.length === 0) { dataJson[table] = []; continue; } // 提取列名和行数据,组装为对象数组 const columns = queryResult[0].columns; const rows = queryResult[0].values; dataJson[table] = rows.map(row => { const rowObj = {}; columns.forEach((colName, index) => { rowObj[colName] = row[index]; }); return rowObj; }); } // 关闭数据库释放内存 db.close(); return dataJson; } // 调用示例 convertSqlToJson('./sample_sql_file.sql') .then(jsonData => { console.log(JSON.stringify(jsonData, null, 2)); // 可选:将结果写入JSON文件 // await fs.writeFile('./output.json', JSON.stringify(jsonData, null, 2)); }) .catch(error => console.error('处理SQL文件失败:', error));
方案2:使用better-sqlite3(高性能,需编译)
如果SQL文件较大、查询量多,better-sqlite3性能更优,同样支持内存模式。
步骤1:安装依赖
npm install better-sqlite3
步骤2:实现代码
import fs from 'fs/promises'; import Database from 'better-sqlite3'; async function convertSqlToJson(sqlFilePath) { // 创建内存数据库 const db = new Database(':memory:'); // 读取并执行SQL文件 const sqlContent = await fs.readFile(sqlFilePath, 'utf8'); db.exec(sqlContent); const dataJson = {}; // 获取所有表名 const tables = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'").all() .map(row => row.name); // 遍历表导出数据 for (const table of tables) { const rows = db.prepare(`SELECT * FROM \`${table}\``).all(); dataJson[table] = rows; } // 关闭数据库 db.close(); return dataJson; } // 调用示例 convertSqlToJson('./sample_sql_file.sql') .then(jsonData => { console.log(JSON.stringify(jsonData, null, 2)); }) .catch(error => console.error('处理失败:', error));
注意事项
- SQL语法兼容性:上述库基于SQLite,与MariaDB的语法存在细微差异(如MariaDB的
AUTO_INCREMENT需改为SQLite的AUTOINCREMENT,部分函数语法不同),若SQL文件包含MariaDB特有语法,需提前做兼容处理。 - 内存占用:若SQL文件极大(如包含百万级数据),内存模式可能导致内存不足,此时可考虑临时磁盘数据库替代,但仍无需外部服务器。
内容的提问来源于stack exchange,提问作者Park
相关产品推荐
相关产品推荐

