funel data

This commit is contained in:
2025-03-11 00:36:22 +08:00
parent 7857a9007a
commit bc42ff4dbf
13 changed files with 2171 additions and 11 deletions

View File

@@ -0,0 +1,177 @@
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();