HaniBlindBox/server/scripts/migrate_danye.js
2026-01-03 14:47:28 +08:00

165 lines
5.5 KiB
JavaScript

/**
* 单页内容数据迁移脚本 - Node.js
*
* 源表: MySQL danye
* 目标表: SQL Server danye
*
* 字段映射:
* - id -> id
* - title -> title
* - content -> content
* - update_time -> update_time
* - status -> status
* - is_image_optimizer -> is_image_optimizer
*/
const mysql = require('mysql2/promise');
const sql = require('mssql');
// MySQL 配置
const mysqlConfig = {
host: '192.168.195.16',
port: 1887,
user: 'root',
password: 'Dbt@com@123',
database: 'youdas',
charset: 'utf8mb4'
};
// SQL Server 配置
const sqlServerConfig = {
server: '192.168.195.15',
port: 1433,
user: 'sa',
password: 'Dbt@com@123',
database: 'honey_box',
options: {
encrypt: false,
trustServerCertificate: true
}
};
// 转义SQL字符串
function escapeString(str) {
if (str === null || str === undefined) return 'NULL';
return "N'" + String(str).replace(/'/g, "''") + "'";
}
// 获取已迁移的ID列表
async function getMigratedIds(pool) {
const result = await pool.request().query('SELECT id FROM danye');
return new Set(result.recordset.map(r => r.id));
}
// 逐条插入数据(因为 content 字段可能很大)
async function insertDanyeOne(pool, danye) {
const sqlStatement = `
SET IDENTITY_INSERT danye ON;
INSERT INTO danye (id, title, content, update_time, status, is_image_optimizer)
VALUES (${danye.id}, ${escapeString(danye.title)}, ${escapeString(danye.content)}, ${danye.update_time}, ${danye.status}, ${danye.is_image_optimizer});
SET IDENTITY_INSERT danye OFF;`;
await pool.request().batch(sqlStatement);
}
async function main() {
console.log('========================================');
console.log('单页内容数据迁移脚本 - Node.js');
console.log('========================================\n');
let mysqlConn = null;
let sqlPool = null;
try {
// 连接 MySQL
console.log('正在连接 MySQL...');
mysqlConn = await mysql.createConnection(mysqlConfig);
console.log('MySQL 连接成功\n');
// 连接 SQL Server
console.log('正在连接 SQL Server...');
sqlPool = await sql.connect(sqlServerConfig);
console.log('SQL Server 连接成功\n');
// 获取已迁移的ID
console.log('正在获取已迁移的单页ID...');
const migratedIds = await getMigratedIds(sqlPool);
console.log(`已迁移单页数: ${migratedIds.size}\n`);
// 从 MySQL 获取所有单页数据
console.log('正在从 MySQL 读取单页数据...');
const [rows] = await mysqlConn.execute(`
SELECT id, title, content, update_time, status, is_image_optimizer
FROM danye
ORDER BY id
`);
console.log(`MySQL 单页总数: ${rows.length}\n`);
// 显示单页列表
console.log('单页列表:');
for (const row of rows) {
const status = migratedIds.has(row.id) ? '已迁移' : '待迁移';
console.log(` ${row.id}. ${row.title} [${status}]`);
}
console.log('');
// 过滤出未迁移的单页
const danyesToMigrate = rows.filter(danye => !migratedIds.has(danye.id));
console.log(`待迁移单页数: ${danyesToMigrate.length}\n`);
if (danyesToMigrate.length === 0) {
console.log('所有单页数据已迁移完成!');
} else {
// 逐条迁移(因为 content 字段可能很大)
console.log('开始迁移单页数据...');
let insertedCount = 0;
for (const danye of danyesToMigrate) {
try {
await insertDanyeOne(sqlPool, danye);
insertedCount++;
console.log(` ✓ 插入单页 ${danye.id}: ${danye.title}`);
} catch (err) {
console.error(` ✗ 插入单页 ${danye.id} (${danye.title}) 失败:`, err.message);
}
}
console.log(`\n迁移完成!共插入 ${insertedCount} 条记录`);
}
// 验证迁移结果
console.log('\n========================================');
console.log('迁移结果验证');
console.log('========================================');
const [mysqlCount] = await mysqlConn.execute('SELECT COUNT(*) as count FROM danye');
const sqlResult = await sqlPool.request().query('SELECT COUNT(*) as count FROM danye');
console.log(`MySQL danye 表记录数: ${mysqlCount[0].count}`);
console.log(`SQL Server danye 表记录数: ${sqlResult.recordset[0].count}`);
if (mysqlCount[0].count === sqlResult.recordset[0].count) {
console.log('\n✅ 数据迁移完成,记录数一致!');
} else {
console.log(`\n⚠️ 记录数不一致,差异: ${mysqlCount[0].count - sqlResult.recordset[0].count}`);
}
// 显示迁移后的单页列表
console.log('\n迁移后的单页列表:');
const migratedDanyes = await sqlPool.request().query('SELECT id, title FROM danye ORDER BY id');
for (const danye of migratedDanyes.recordset) {
console.log(` ${danye.id}. ${danye.title}`);
}
} catch (err) {
console.error('迁移过程中发生错误:', err);
process.exit(1);
} finally {
// 关闭连接
if (mysqlConn) await mysqlConn.end();
if (sqlPool) await sqlPool.close();
}
}
main();