def InterfaceUpload(): """上传任务流配置文件""" # 文件路径 file_dir = './uploads' # 文件类型 file_type = {'xlsx', 'xls', 'csv'} # 异常类型 err_type = { 0: '第%s行[序号]参数不为整型', 1: '第%s行[任务流名称]参数不为字符串类型', 2: '第%s行[任务流描述]参数不为字符串类型', 3: '第%s行[任务流目录]参数不为字符串类型', 5: '第%s行[重试次数]参数不为整型', 6: '第%s行[依赖任务流序号(本次新建任务流)]参数不为整型或没按逗号分隔', 7: '第%s行[依赖任务流id(已有任务流)]参数不为空或整型或没按逗号分隔' } file = request.files['file'] # 获取文件名 file_name = file.filename # 获取文件后缀 file_suffix = '.' in file_name and file_name.rsplit('.', 1)[1] if file and file_suffix in file_type: # 保存文件到upload目录 file_path = os.path.join(file_dir, file_name) file.save(file_path) # 异常原因 err_msg = [] # excel文件 if file_suffix in {'xlsx', 'xls'}: data = xlrd.open_workbook(file_path) # 只取第一个sheet sheet = data.sheet_by_name(data.sheet_names()[0]) # 从第2行开始读取 data = [] for i in range(1, sheet.nrows): # 取前8列 item = sheet.row_values(i)[:8] try: # 日期格式转换 if item[4]: item[4] = xlrd.xldate_as_tuple(item[4], 0) item[4] = datetime.date(*item[4][:3]).strftime('%Y-%m-%d') else: item[4] = None except: item[4] = None err_msg.append('第%s行[数据日期]参数格式错误' % (i + 1)) data.append(item) # csv文件 else: data = [] with open(file_path, "r") as csv_file: reader = csv.reader(csv_file) for index, line in enumerate(reader): if index > 0: # 取前8列 item = line[:8] try: # 日期格式转换 date_value = re.findall(r'(\d{4}).(\d{1,2}).(\d{1,2})', item[4]) if date_value: item[4] = '%04d-%02d-%02d' % tuple(int(item) for item in date_value[0]) else: item[4] = (date.today() + timedelta(days=-1)).strftime('%Y-%m-%d') except: item[4] = None err_msg.append('第%s行[数据日期]参数格式错误' % (index + 1)) data.append(item) # 任务流id列表 interface_result = InterfaceModel.get_interface_id_list(db.etl_db) interface_ids = [i['interface_id'] for i in interface_result] # 文件为空 if not data: err_msg.append('文件为空') # [依赖任务流序号(本次新建任务流)]列表 curr_interface_num = [] for index, row in enumerate(data): # Excel行号 row_num = index + 2 # 校验列数 if len(row) < 8: err_msg.append('第%s行参数个数小于8个' % row_num) else: # 校验并处理每列参数 for i, param in enumerate(row): try: # int类型参数 if i in [0, 5]: row[i] = int(param) # 添加[依赖任务流序号(本次新建任务流)] if i == 0: curr_interface_num.append(row[i]) # 字符串类型参数 elif i in [1, 2, 3]: row[i] = str(param) # 依赖任务流 elif i in [6, 7]: if isinstance(param, str): if param != '': row[i] = [int(i) for i in str(param).split(',')] else: row[i] = [] else: row[i] = [int(param)] except: err_msg.append(err_type[i] % row_num) for i, param in enumerate(row): # [任务流名称]判空 if i == 1 and param == '': err_msg.append('第%s行[任务流名称]参数不得为空' % row_num) # [任务流名称]数据库查重 if i == 1 and param != '': if InterfaceModel.get_interface_detail_by_name(db.etl_db, param): err_msg.append('第%s行[任务流名称]参数已存在数据库中' % row_num) # [任务流目录]判空 if i == 3 and param == '': err_msg.append('第%s行[任务流目录]参数不得为空' % row_num) # [重试次数]次数限制 if i == 5 and isinstance(param, int) and (param < 0 or param > 10): err_msg.append('第%s行[重试次数]参数请限制在0-10之内' % row_num) # [依赖任务流序号(本次新建任务流)]判空 if i == 6 and isinstance(param, list): for item in param: if item not in curr_interface_num: err_msg.append('第%s行[依赖任务流序号(本次新建任务流)][%s]不存在' % (row_num, item)) # [依赖任务流id(已有任务流)]数据库判空 if i == 7 and isinstance(param, list): for item in param: if item not in interface_ids: err_msg.append('第%s行[依赖任务流id(已有任务流)][%s]不存在' % (row_num, item)) # [序号]是否重复 serial_num = [row[0] for row in data] if len(serial_num) != len(set(serial_num)): err_msg.append('该文件中[序号]存在重复') # [任务流名称]文件内查重 serial_name = [row[1] for row in data] if len(serial_name) != len(set(serial_name)): err_msg.append('该文件中[任务流名称]存在重复') # 返回异常信息 if err_msg: # 删除文件 os.remove(file_path) return jsonify({'status': 401, 'msg': '文件参数错误', 'data': {'err_msg': err_msg}}) # 写入数据库 else: # 用户id user_info = curr_session.get_info() user_id = user_info['id'] # 依赖任务流序号 -> 任务流id映射 interface_map = {} for item in data: # 新增任务流 interface_id = InterfaceModel.add_interface(db.etl_db, item[1], item[2], item[3], item[4], item[5], user_id) # 添加映射 interface_map[item[0]] = interface_id # 表格数据中新增任务流id字段 item.append(interface_id) # 新增任务流依赖 parent_arr = [] for line in data: parent_interface = [] # [依赖任务流序号(本次新建任务流)]映射 if line[6]: parent_interface = [interface_map[i] for i in line[6]] # [依赖任务流id(已有任务流)] if line[7]: # 合并数组 parent_interface += line[7] for parent_id in parent_interface: parent_arr.append({ # 最后一位为新增的任务id字段 'interface_id': line[len(line) - 1], 'parent_id': parent_id, 'insert_time': int(time.time()), 'update_time': int(time.time()), 'creator_id': user_id, 'updater_id': user_id }) InterfaceModel.add_interface_parent(db.etl_db, parent_arr) if parent_arr else None # 删除文件 os.remove(file_path) return jsonify({'status': 200, 'msg': '成功', 'data': {}}) else: return jsonify({'status': 400, 'msg': '文件类型错误', 'data': {}})
def JobUpload(): """上传任务配置文件""" # 文件路径 file_dir = './uploads' # 文件类型 file_type = {'xlsx', 'xls', 'csv'} # 异常类型 err_type = { 0: '第%s行[序号]参数不为整型', 1: '第%s行[所属任务流id]参数不为整型', 2: '第%s行[任务名称]参数不为字符串类型', 3: '第%s行[任务描述]参数不为字符串类型', 4: '第%s行[服务器id]参数不为整型', 5: '第%s行[任务目录]参数不为字符串类型', 6: '第%s行[脚本目录]参数不为字符串类型', 7: '第%s行[脚本命令]参数不为字符串类型', 8: '第%s行[依赖任务序号(本次新建任务)]参数不为整型或没按逗号分隔', 9: '第%s行[依赖任务id(已有任务)]参数不为空或整型或没按逗号分隔', 10: '第%s行[任务参数]不为空或整型或没按逗号分隔', 11: '第%s行[返回值]参数不为整型' } file = request.files['file'] # 获取文件名 file_name = file.filename # 获取文件后缀 file_suffix = '.' in file_name and file_name.rsplit('.', 1)[1] if file and file_suffix in file_type: # 保存文件到upload目录 file_path = os.path.join(file_dir, file_name) file.save(file_path) # excel文件 if file_suffix in {'xlsx', 'xls'}: data = xlrd.open_workbook(file_path) # 只取第一个sheet sheet = data.sheet_by_name(data.sheet_names()[0]) # 从第2行开始读取 data = [] for i in range(1, sheet.nrows): # 取前12列 data.append(sheet.row_values(i)[:12]) # csv文件 else: data = [] with open(file_path, "r") as csv_file: reader = csv.reader(csv_file) for index, line in enumerate(reader): if index > 0: # 取前12列 data.append(line[:12]) # 异常原因 err_msg = [] # 任务流id列表 interface_result = InterfaceModel.get_interface_id_list(db.etl_db) interface_ids = [i['interface_id'] for i in interface_result] # 服务器id列表 exec_host_result = ExecHostModel.get_exec_host_all(db.etl_db) exec_host_ids = [i['server_id'] for i in exec_host_result] # 依赖任务id(已有任务)列表 job_result = JobModel.get_job_list_all(db.etl_db) job_ids = [i['job_id'] for i in job_result] # 任务参数列表 job_params = ParamsModel.get_params_all(db.etl_db) job_params_ids = [i['param_id'] for i in job_params] # 文件为空 if not data: err_msg.append('文件为空') # [依赖任务序号(本次新建任务)]列表 curr_job_num = [] for index, row in enumerate(data): # Excel行号 row_num = index + 2 # 校验列数 if len(row) < 10: err_msg.append('第%s行参数个数小于10个' % row_num) else: # 校验并处理每列参数 for i, param in enumerate(row): try: # int类型参数 if i in [0, 1, 4, 11]: row[i] = int(param) # 添加[依赖任务序号(本次新建任务)] if i == 0: curr_job_num.append(row[i]) # 字符串类型参数 elif i in [2, 3, 5, 6, 7]: row[i] = str(param) # 依赖任务 else: if isinstance(param, str): if param != '': row[i] = [int(i) for i in str(param).split(',')] else: row[i] = [] else: row[i] = [int(param)] except: err_msg.append(err_type[i] % row_num) for i, param in enumerate(row): # [所属任务流id]判空 if i == 1 and isinstance(param, int): if param not in interface_ids: err_msg.append('第%s行[所属任务流id]不存在' % row_num) # [任务名称]判空 if i == 2 and param == '': err_msg.append('第%s行[任务名称]参数不得为空' % row_num) # [任务名称]数据库查重 if i == 2 and param != '': if JobModel.get_job_detail_by_name(db.etl_db, param): err_msg.append('第%s行[任务名称]参数已存在数据库中' % row_num) # [服务器id]判空 if i == 4 and isinstance(param, int): if param not in exec_host_ids: err_msg.append('第%s行[服务器id]不存在' % row_num) # [任务目录]判空和","字符串 if i == 5: if param == '': err_msg.append('第%s行[任务目录]参数不得为空' % row_num) elif re.findall(',', param): err_msg.append('第%s行[任务目录]参数不得出现逗号字符","' % row_num) # [脚本目录]判空 if i == 6 and param == '': err_msg.append('第%s行[脚本目录]参数不得为空' % row_num) # [脚本命令]判空 if i == 7 and param == '': err_msg.append('第%s行[脚本命令]参数不得为空' % row_num) # [依赖任务序号(本次新建任务)]数据库判空 if i == 8 and isinstance(param, list): for job_num in param: if job_num not in curr_job_num: err_msg.append('第%s行[依赖任务序号(本次新建任务)][%s]不存在' % (row_num, job_num)) # [依赖任务id(已有任务)]数据库判空 if i == 9 and isinstance(param, list): for job_id in param: if job_id not in job_ids: err_msg.append('第%s行[依赖任务id(已有任务)][%s]不存在' % (row_num, job_id)) # [任务参数]数据库判空 if i == 10 and isinstance(param, list): for job_param in param: if job_param not in job_params_ids: err_msg.append('第%s行[任务参数][%s]不存在' % (row_num, job_param)) # [序号]是否重复 serial_num = [row[0] for row in data] if len(serial_num) != len(set(serial_num)): err_msg.append('该文件中[序号]存在重复') # 返回异常信息 if err_msg: # 删除文件 os.remove(file_path) return jsonify({'status': 401, 'msg': '文件类型错误', 'data': {'err_msg': err_msg}}) # 写入数据库 else: # 用户id user_info = curr_session.get_info() user_id = user_info['id'] # 依赖任务序号 -> 任务id映射 job_map = {} for line in data: # 新增任务详情 job_id = JobModel.add_job_detail(db.etl_db, line[2], line[1], line[3], line[5], line[4], line[6], line[7], line[11], user_id) # 添加映射 job_map[line[0]] = job_id # 表格数据中新增任务id字段 line.append(job_id) # 新增任务依赖 prep_data = [] for line in data: prep_job = [] # 本次新增任务序号与任务id映射 if line[8]: prep_job = [job_map[i] for i in line[8]] if line[9]: # 合并数组 prep_job += line[9] for prep_id in prep_job: prep_data.append({ # 最后一位为新增的任务id字段 'job_id': line[len(line) - 1], 'prep_id': prep_id, 'user_id': user_id, 'insert_time': int(time.time()), 'update_time': int(time.time()) }) JobModel.add_job_prep(db.etl_db, prep_data) if prep_data else None # 新增任务参数 job_params = [] for line in data: for param_id in line[10]: job_params.append({ # 最后一位为新增的任务id字段 'job_id': line[len(line) - 1], 'param_id': param_id, 'insert_time': int(time.time()), 'update_time': int(time.time()), 'user_id': user_id }) JobModel.add_job_param(db.etl_db, job_params) if job_params else None # 删除文件 os.remove(file_path) return jsonify({'status': 200, 'msg': '成功', 'data': {}}) else: return jsonify({'status': 400, 'msg': '文件类型错误', 'data': {}})
def get_interface_id_list(): """获取接口id列表""" result = InterfaceModel.get_interface_id_list(db.etl_db) return Response(result=result)