Files

116 lines
3.8 KiB
JavaScript
Raw Permalink Normal View History

/**
* 操作日志表添加 requestId 字段和索引
* 支持请求追踪ID关联,优化查询性能
* 支持 SQLite 和 MySQL,幂等执行
*/
require('dotenv').config({ path: require('path').join(__dirname, '../.env') });
const { sequelize, dbDialect } = require('../db');
async function getTableColumns(tableName) {
const dialect = sequelize.getDialect();
if (dialect === 'sqlite') {
const tableInfo = await sequelize.query(`PRAGMA table_info(${tableName})`, {
type: sequelize.QueryTypes.SELECT,
});
return tableInfo.map(col => col.name);
}
const tableInfo = await sequelize.query(`SHOW COLUMNS FROM ${tableName}`, {
type: sequelize.QueryTypes.SELECT,
});
return tableInfo.map(col => col.Field);
}
async function tableExists(tableName) {
const dialect = sequelize.getDialect();
if (dialect === 'sqlite') {
const tables = await sequelize.query(
"SELECT name FROM sqlite_master WHERE type='table' AND name=?",
{ replacements: [tableName], type: sequelize.QueryTypes.SELECT }
);
return tables.length > 0;
}
const tables = await sequelize.query('SHOW TABLES LIKE ?', {
replacements: [tableName],
type: sequelize.QueryTypes.SELECT,
});
return tables.length > 0;
}
async function addColumnIfNotExists(tableName, columnName, columnDef) {
const columns = await getTableColumns(tableName);
if (!columns.includes(columnName)) {
await sequelize.query(`ALTER TABLE ${tableName} ADD COLUMN ${columnName} ${columnDef}`);
console.log(` ${tableName} 表添加 ${columnName} 字段成功`);
} else {
console.log(` ${tableName}${columnName} 字段已存在,跳过`);
}
}
async function addIndexIfNotExists(tableName, indexName, fields) {
const dialect = sequelize.getDialect();
try {
if (dialect === 'sqlite') {
await sequelize.query(
`CREATE INDEX IF NOT EXISTS ${indexName} ON ${tableName}(${fields.join(', ')})`
);
} else {
const [indexes] = await sequelize.query(
`SELECT INDEX_NAME FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = ? AND INDEX_NAME = ? AND TABLE_SCHEMA = DATABASE()`,
{ replacements: [tableName, indexName], type: sequelize.QueryTypes.SELECT }
);
if (!indexes || indexes.length === 0) {
await sequelize.query(
`CREATE INDEX \`${indexName}\` ON \`${tableName}\`(\`${fields.join('`, `')}\`)`
);
} else {
console.log(` 索引 ${indexName} 已存在,跳过`);
return;
}
}
console.log(` 索引 ${indexName} 创建成功`);
} catch (error) {
if (error.message.includes('already exists') || error.message.includes('Duplicate key name')) {
console.log(` 索引 ${indexName} 已存在,跳过`);
} else {
throw error;
}
}
}
async function migrateOperationLogRequestId() {
const tableName = 'operation_logs';
if (!(await tableExists(tableName))) {
console.log(` ${tableName} 表不存在,跳过`);
return;
}
await addColumnIfNotExists(tableName, 'requestId', 'VARCHAR(255)');
await addIndexIfNotExists(tableName, 'operation_logs_requestId', ['requestId']);
await addIndexIfNotExists(tableName, 'operation_logs_module_createdAt', ['module', 'createdAt']);
console.log(' 操作日志requestId字段和索引迁移完成');
}
async function run() {
console.log('========================================');
console.log(' 操作日志表添加requestId字段迁移脚本 ');
console.log('========================================');
console.log(`数据库类型: ${dbDialect}`);
try {
await migrateOperationLogRequestId();
console.log('\n迁移完成');
} catch (error) {
console.error('迁移失败:', error.message);
process.exit(1);
} finally {
await sequelize.close();
}
}
run();