177 lines
4.9 KiB
JavaScript
177 lines
4.9 KiB
JavaScript
require('dotenv').config();
|
||
const { createClient } = require('@clickhouse/client');
|
||
const http = require('http');
|
||
|
||
// 创建ClickHouse客户端
|
||
const client = createClient({
|
||
host: `http://${process.env.CLICKHOUSE_HOST || 'localhost'}:${process.env.CLICKHOUSE_PORT || 8123}`,
|
||
username: process.env.CLICKHOUSE_USER || 'default',
|
||
password: process.env.CLICKHOUSE_PASSWORD || '',
|
||
database: process.env.CLICKHOUSE_DATABASE || 'promote',
|
||
});
|
||
|
||
// 使用HTTP直接发送请求到ClickHouse
|
||
function sendClickHouseQuery(query) {
|
||
return new Promise((resolve, reject) => {
|
||
// 添加认证信息
|
||
const username = process.env.CLICKHOUSE_USER || 'default';
|
||
const password = process.env.CLICKHOUSE_PASSWORD || '';
|
||
const auth = Buffer.from(`${username}:${password}`).toString('base64');
|
||
|
||
const options = {
|
||
hostname: process.env.CLICKHOUSE_HOST || 'localhost',
|
||
port: process.env.CLICKHOUSE_PORT || 8123,
|
||
path: `/?database=${process.env.CLICKHOUSE_DATABASE || 'promote'}&enable_http_compression=1`,
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'text/plain',
|
||
'Authorization': `Basic ${auth}`
|
||
}
|
||
};
|
||
|
||
const req = http.request(options, (res) => {
|
||
let data = '';
|
||
|
||
res.on('data', (chunk) => {
|
||
data += chunk;
|
||
});
|
||
|
||
res.on('end', () => {
|
||
if (res.statusCode >= 200 && res.statusCode < 300) {
|
||
resolve(data);
|
||
} else {
|
||
reject(new Error(`HTTP Error: ${res.statusCode} - ${data}`));
|
||
}
|
||
});
|
||
});
|
||
|
||
req.on('error', (error) => {
|
||
reject(error);
|
||
});
|
||
|
||
req.write(query);
|
||
req.end();
|
||
});
|
||
}
|
||
|
||
// 检查ClickHouse服务器是否可用
|
||
async function checkClickHouseConnection() {
|
||
console.log('检查ClickHouse连接...');
|
||
|
||
try {
|
||
const result = await sendClickHouseQuery('SELECT 1');
|
||
console.log('ClickHouse连接成功');
|
||
return true;
|
||
} catch (error) {
|
||
console.error('ClickHouse连接失败:', error.message);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
// 获取表的数据量
|
||
async function getTableCount(tableName) {
|
||
try {
|
||
const result = await sendClickHouseQuery(`SELECT count() as count FROM ${tableName} FORMAT JSON`);
|
||
const data = JSON.parse(result);
|
||
return data.data[0].count;
|
||
} catch (error) {
|
||
console.error(`获取表 ${tableName} 数据量失败:`, error.message);
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
// 获取表的样本数据
|
||
async function getTableSample(tableName, limit = 5) {
|
||
try {
|
||
const result = await sendClickHouseQuery(`SELECT * FROM ${tableName} LIMIT ${limit} FORMAT JSON`);
|
||
const data = JSON.parse(result);
|
||
return data.data;
|
||
} catch (error) {
|
||
console.error(`获取表 ${tableName} 样本数据失败:`, error.message);
|
||
return [];
|
||
}
|
||
}
|
||
|
||
// 获取表的结构
|
||
async function getTableStructure(tableName) {
|
||
try {
|
||
const result = await sendClickHouseQuery(`DESCRIBE TABLE ${tableName} FORMAT JSON`);
|
||
const data = JSON.parse(result);
|
||
return data.data;
|
||
} catch (error) {
|
||
console.error(`获取表 ${tableName} 结构失败:`, error.message);
|
||
return [];
|
||
}
|
||
}
|
||
|
||
// 获取所有表
|
||
async function getAllTables() {
|
||
try {
|
||
const result = await sendClickHouseQuery(`
|
||
SELECT name
|
||
FROM system.tables
|
||
WHERE database = '${process.env.CLICKHOUSE_DATABASE || 'promote'}'
|
||
FORMAT JSON
|
||
`);
|
||
const data = JSON.parse(result);
|
||
return data.data.map(row => row.name);
|
||
} catch (error) {
|
||
console.error('获取所有表失败:', error.message);
|
||
return [];
|
||
}
|
||
}
|
||
|
||
// 主函数
|
||
async function main() {
|
||
console.log('开始检查ClickHouse数据...');
|
||
|
||
try {
|
||
// 检查ClickHouse连接
|
||
const connectionOk = await checkClickHouseConnection();
|
||
if (!connectionOk) {
|
||
console.error('无法连接到ClickHouse服务器,请检查配置和服务器状态');
|
||
return;
|
||
}
|
||
|
||
// 获取所有表
|
||
const tables = await getAllTables();
|
||
console.log(`\n数据库中的表 (${tables.length}):`);
|
||
console.log(tables);
|
||
|
||
// 检查每个表的数据
|
||
for (const table of tables) {
|
||
console.log(`\n表: ${table}`);
|
||
|
||
// 获取表结构
|
||
const structure = await getTableStructure(table);
|
||
console.log('表结构:');
|
||
console.table(structure.map(col => ({
|
||
name: col.name,
|
||
type: col.type,
|
||
default_type: col.default_type,
|
||
default_expression: col.default_expression
|
||
})));
|
||
|
||
// 获取数据量
|
||
const count = await getTableCount(table);
|
||
console.log(`数据量: ${count} 行`);
|
||
|
||
// 获取样本数据
|
||
if (count > 0) {
|
||
const samples = await getTableSample(table);
|
||
console.log('样本数据:');
|
||
console.table(samples);
|
||
}
|
||
}
|
||
|
||
console.log('\nClickHouse数据检查完成!');
|
||
} catch (error) {
|
||
console.error('检查ClickHouse数据过程中发生错误:', error);
|
||
} finally {
|
||
// 关闭客户端连接
|
||
await client.close();
|
||
}
|
||
}
|
||
|
||
// 执行主函数
|
||
main();
|