Skip to main content
Glama
superset-api.ts8.19 kB
/** * Superset API 服务 * 提供与Superset API交互的高级方法 */ import { SupersetHttpClient, } from '../utils/http-client.js'; // 数据库模型 export interface Database { id: number; database_name: string; sqlalchemy_uri: string; expose_in_sqllab: boolean; allow_run_async: boolean; allow_dml: boolean; allow_file_upload: boolean; allow_ctas: boolean; allow_cvas: boolean; extra: string; [key: string]: any; } // 表模型 export interface Table { name: string; schema: string; catalog: string; description?: string; [key: string]: any; } // 字段模型 export interface Field { name: string; type: string; nullable?: boolean; default?: any; comment?: string | null; longType?: string; keys?: any[]; [key: string]: any; } // 表元数据模型 export interface TableMetadata { columns: Field[]; comment: string | null; foreignKeys: any[]; indexes: Array<{ column_names: string[]; name: string; type: string; unique: boolean; }>; name: string; primaryKey: { constrained_columns: string[] | null; name: string | null; }; selectStar: string; [key: string]: any; } // 查询请求模型 export interface QueryRequest { database_id: number; sql: string; catalog?: string; client_id?: string; ctas_method?: string; expand_data?: boolean; json?: boolean; queryLimit?: number; runAsync?: boolean; schema?: string; select_as_cta?: boolean; sql_editor_id?: string; tab?: string; templateParams?: string; tmp_table_name?: string; [key: string]: any; } // 查询结果模型 export interface QueryResult { status: string; data: any[]; columns: any[]; selected_columns: any[]; expanded_columns: any[]; query_id: number; query?: { changed_on: string; ctas: boolean; db: string; dbId: number; endDttm: number; errorMessage: string; executedSql: string; extra: any; id: string; limit: number; limitingFactor: string; progress: number; queryId: number; resultsKey: string; rows: number; schema: string; serverId: number; sql: string; sqlEditorId: string; startDttm: number; state: string; tab: string; tempSchema: string; tempTable: string; trackingUrl: string; user: string; userId: number; }; [key: string]: any; } export class SupersetApiService { private client: SupersetHttpClient; constructor({ baseUrl, username, password, withCredentials = true, }: { baseUrl: string; username: string; password: string; withCredentials?: boolean; }) { this.client = new SupersetHttpClient({ baseUrl, username, password, withCredentials, }); } /** * 获取所有数据库列表 */ public async getDatabases(): Promise<Database[]> { const response = await this.client.get<{ result: Database[] }>('/api/v1/database/'); if (!response.success || !response.data?.result) { throw new Error(response.error?.message || '获取数据库列表失败'); } return response.data.result; } /** * 获取特定数据库详情 */ public async getDatabase(id: number): Promise<Database> { const response = await this.client.get<{ result: Database }>(`/api/v1/database/${id}`); if (!response.success || !response.data?.result) { throw new Error(response.error?.message || `获取数据库ID ${id} 详情失败`); } return response.data.result; } /** * 获取特定数据库的所有schema */ public async getSchemas(databaseId: number): Promise<string[]> { const response = await this.client.get<{ result: string[] }>(`/api/v1/database/${databaseId}/schemas/?q=(force:!t)`); if (!response.success || !response.data?.result) { throw new Error(response.error?.message || `获取数据库ID ${databaseId} 的schema列表失败`); } return response.data.result; } /** * 获取特定数据库和schema的所有表 */ public async getTables(databaseId: number, schemaName: string): Promise<Table[]> { try { // 使用新的查询参数格式 const queryParams = `q=(force:!f,schema_name:${encodeURIComponent(schemaName)})`; console.log(`尝试使用新的表列表API: /api/v1/database/${databaseId}/tables/?${queryParams}`); const response = await this.client.get<{ result: Table[] }>( `/api/v1/database/${databaseId}/tables/?${queryParams}` ); if (response.success && response.data?.result) { // 打印第一个表的结构,以便了解API返回的数据格式 if (response.data.result.length > 0) { console.log('表数据结构示例:', JSON.stringify(response.data.result[0], null, 2)); } // 将API返回的表结构转换为我们的Table接口格式 return response.data.result.map((item: any) => ({ name: item.value || '', schema: schemaName, catalog: item.catalog || '', description: item.description || '', ...item })); } throw new Error(response.error?.message || `获取数据库ID ${databaseId} 的表列表失败`); } catch (error) { console.error('获取表列表失败:', error); throw error; } } /** * 获取表的元数据信息 */ public async getTableMetadata(databaseId: number, schemaName: string, tableName: string): Promise<TableMetadata> { try { // 使用新的 API 路径格式 console.log(`尝试使用表元数据API: /api/v1/database/${databaseId}/table/${tableName}/${schemaName}/`); const response = await this.client.get<TableMetadata>( `/api/v1/database/${databaseId}/table/${tableName}/${schemaName}/` ); if (!response.success || !response.data) { throw new Error(response.error?.message || `获取表 ${schemaName}.${tableName} 的元数据失败`); } return response.data; } catch (error) { console.error('获取表元数据失败:', error); throw error; } } /** * 执行SQL查询 */ public async executeQuery(request: QueryRequest): Promise<QueryResult> { try { // 确保必要的参数 if (!request.database_id || !request.sql) { throw new Error('执行查询需要提供 database_id 和 sql 参数'); } // 设置默认值 const queryRequest: QueryRequest = { ...request, client_id: request.client_id || `client_${Date.now()}`, sql_editor_id: request.sql_editor_id || `editor_${Date.now()}`, runAsync: request.runAsync !== undefined ? request.runAsync : false, json: true }; const response = await this.client.post<QueryResult>('/api/v1/sqllab/execute/', queryRequest); console.log(response) if (!response.success) { throw new Error(response.error?.message || '执行查询失败'); } return response.data as QueryResult; } catch (error) { console.error('执行查询失败:', error); throw error; } } /** * 获取查询结果 */ public async getQueryResults(queryId: number): Promise<QueryResult> { try { const response = await this.client.get<QueryResult>(`/api/v1/sqllab/results/${queryId}/`); if (!response.success) { throw new Error(response.error?.message || `获取查询ID ${queryId} 的结果失败`); } return response.data as QueryResult; } catch (error) { console.error('获取查询结果失败:', error); throw error; } } /** * 取消正在执行的查询 */ public async cancelQuery(queryId: number): Promise<boolean> { try { const response = await this.client.post<{ message: string }>('/api/v1/sqllab/cancel_query/', { query_id: queryId }); return response.success; } catch (error) { console.error('取消查询失败:', error); return false; } } /** * 获取客户端实例 */ public getClient(): SupersetHttpClient { return this.client; } }

Implementation Reference

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/LiusCraft/superset-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server