# coding=utf-8 """ @Author: fu-zhe @FileName: db2json.py @DateTime: 2024/5/15 10:19 @Description: 数据库工具查询之后的数据为 list嵌套 需要转换成 前端方便识别的json数据 """ import json import traceback from dataInterface.functions import CFunction from dataInterface.db.params import CPgSqlParam from uebaMetricsAnalysis.utils.ext_logging import logger class DBType(object): LIST = 'list' DICT = 'dict' JOB_TABLE_NAME = "ueba_clean_jobs" ANALYSIS_TABLE_NAME = "ueba_analysis_log" class DBUtils(object): @classmethod def transition(cls, filed, sql, data_type): """ 数据转换 将json格式的data转换成前端方便使用的 json :param data_type: 转换数据类型 目前有 list dict两种 :param filed: list 格式 数据库字段 例如 select id, name from table; filed= ['id','name'] :param sql: sql语句 `select * from table` :return: [{filed1: value1, filed2: value2,···}, ····] 或 {filed1: value1, filed2: value2,···} """ data = cls.execute(sql=sql) if cls.is_list_of_empty_lists(data): return eval(data_type)() if data_type == DBType.DICT: data = data[0] if len(filed) != len(data): raise Exception("{}与数据库查询结果长度不一致".format(filed)) res = {cls.snake2camel(filed[i]): data[i] for i in range(len(filed))} logger.info("res = {}".format(res)) return res if data_type == DBType.LIST: res = [] if not data: return res for item in data: if len(item) != len(filed): raise Exception("{}与数据库查询结果长度不一致".format(filed)) res.append({cls.snake2camel(filed[i]): item[i] for i in range(len(filed))}) return res @classmethod def snake2camel(cls, snake_filed): """ 蛇形命名转换小驼峰命名 :param snake_filed: 蛇形命名 例如 user_name :return: 驼峰命名 user_name ---> userName """ if not snake_filed or not isinstance(snake_filed, str): return snake_filed parts = snake_filed.split('_') # 转换第一个单词为小写,其余单词首字母大写 camel = parts[0] + ''.join(word.capitalize() for word in parts[1:]) return camel @classmethod def execute(cls, sql): """ 执行sql语句 :param sql: sql语句 :return: """ try: sql_list = CPgSqlParam(sql) logger.info("execute sql :\n {}\n".format(sql)) data = CFunction.execute(sql_list) logger.info("execute result : {}".format(data)) return json.loads(data) except Exception as e: logger.error("execute sql error sql: \n {}\n tracback: {}\n".format(sql, traceback.format_exc())) raise Exception("查询失败") @classmethod def is_list_of_empty_lists(cls, target_list): # 更清晰地检查每个子列表是否为空 return all(not sublist or len(sublist) == 0 for sublist in target_list) @classmethod def list_snake2camel(cls, snake_list): """ 将列表中 字典的snake命名变成camel命名格式 :param snake_list: list内部都是蛇形命名的dict `[{'user_name':'', 'user_age': ''}]` :return: `[{'user_name':'', 'user_age': ''}]` ----> `[{'userName':'', 'userAge':''}]` """ camel_list = [] for snake_dict in snake_list: camel_list.append({cls.snake2camel(snake): value for snake, value in snake_dict.items()}) return camel_list @classmethod def write_job_status(self,job_id,status,err): sql = """update {JOB_TABLE_NAME} set status=%s err=%s where job_id=%s """.format(JOB_TABLE_NAME=JOB_TABLE_NAME) CFunction.execute(CPgSqlParam(sql, params=(status, err, job_id))) @classmethod def insert_job_record(self,job_id,start_time,end_time,status): sql = """insert into {JOB_TABLE_NAME}(job_id,start_time,end_time,status) values(%s,%s,%s,%s)""".format(JOB_TABLE_NAME=JOB_TABLE_NAME) CFunction.execute(CPgSqlParam(sql, params=(job_id,start_time, end_time,status)))