如何用Python基于ParentID重建文件夹层级并实现跨系统迁移
文件夹跨系统迁移的Python实现思路
需求概述
- 需通过API将系统1的文件夹结构迁移至系统2
- 系统1可返回包含文件夹名称、ID、ParentID、层级深度等字段的结构化数据
- 系统2创建文件夹仅需传入ParentID和文件夹名称,迁移前需先检查系统2中是否已存在对应文件夹
系统1返回数据示例
[{'depth': 0, 'description': None, 'display_order': 55, 'id': 1, 'name': 'Library', 'parent_id': None, 'suite_id': 8}, {'depth': 1, 'description': None, 'display_order': 57, 'id': 529466, 'name': 'MYK [RE]', 'parent_id': 1, 'suite_id': 8}, {'depth': 2, 'description': None, 'display_order': 59, 'id': 530931, 'name': 'MY BO', 'parent_id': 529466, 'suite_id': 8}, {'depth': 3, 'description': None, 'display_order': 60, 'id': 533682, 'name': 'NU Robs', 'parent_id': 530931, 'suite_id': 8}]
已有代码片段
folders = client.send_get('get_sections/1') for i in folders: response = requests.request( "GET", url_f, headers=headers, ) zp_folders = response.json() # here we could check existed folders by name
具体实现思路
1. 按层级排序文件夹
文件夹是树状结构,必须**按层级从浅到深(depth从小到大)**处理,否则父文件夹未创建时子文件夹会创建失败。先对系统1返回的文件夹列表排序:
# 按层级深度升序排序,确保先处理父文件夹 folders_sorted = sorted(folders, key=lambda x: x['depth'])
2. 缓存系统2文件夹信息,减少重复请求
当前代码每次循环都调用GET请求,效率极低。建议一次性拉取系统2全量文件夹,构建快速查询的映射结构:
def get_zp_folder_mappings(url_f, headers): response = requests.get(url_f, headers=headers) zp_folders = response.json() # 构建 (父ID, 文件夹名) -> 系统2文件夹ID 的映射,用于快速查找 folder_id_map = {} # 构建 父ID -> 子文件夹名称集合 的映射,用于快速校验是否存在 parent_children_map = {} for folder in zp_folders: pid = folder['parent_id'] name = folder['name'] folder_id_map[(pid, name)] = folder['id'] if pid not in parent_children_map: parent_children_map[pid] = set() parent_children_map[pid].add(name) return folder_id_map, parent_children_map # 初始化映射(只执行一次) folder_id_map, parent_children_map = get_zp_folder_mappings(url_f, headers) # 额外维护系统1文件夹ID到系统2文件夹ID的映射,用于子文件夹找父ID sys1_to_sys2_id = {}
3. 循环校验并创建文件夹
遍历排序后的系统1文件夹,完成存在性校验与创建逻辑:
# 替换为系统2的根文件夹实际ID(比如0或其他指定值) ZP_ROOT_ID = 0 for folder in folders_sorted: sys1_name = folder['name'] sys1_pid = folder['parent_id'] sys1_id = folder['id'] # 确定系统2中的父文件夹ID if sys1_pid is None: zp_pid = ZP_ROOT_ID else: zp_pid = sys1_to_sys2_id.get(sys1_pid) if not zp_pid: print(f"父文件夹【ID:{sys1_pid}】未在系统2创建,跳过子文件夹【{sys1_name}】") continue # 检查当前文件夹是否已存在 if zp_pid in parent_children_map and sys1_name in parent_children_map[zp_pid]: zp_folder_id = folder_id_map[(zp_pid, sys1_name)] sys1_to_sys2_id[sys1_id] = zp_folder_id print(f"文件夹【{sys1_name}】已存在,跳过") continue # 调用系统2创建文件夹API create_payload = {"parent_id": zp_pid, "name": sys1_name} create_res = requests.post( url=url_create_folder, # 替换为系统2创建文件夹的API地址 headers=headers, json=create_payload ) if create_res.status_code == 201: created_folder = create_res.json() zp_folder_id = created_folder['id'] print(f"成功创建文件夹【{sys1_name}】,系统2ID: {zp_folder_id}") # 更新本地映射 folder_id_map[(zp_pid, sys1_name)] = zp_folder_id if zp_pid not in parent_children_map: parent_children_map[zp_pid] = set() parent_children_map[zp_pid].add(sys1_name) sys1_to_sys2_id[sys1_id] = zp_folder_id else: print(f"创建文件夹【{sys1_name}】失败,状态码: {create_res.status_code},响应: {create_res.text}")
4. 额外优化建议
- 加入异常捕获:对网络请求异常、JSON解析异常做处理,避免脚本中途崩溃
- 替换
print为logging模块,方便后续排查问题 - 若系统支持批量创建API,可按层级批量提交请求,提升迁移效率
内容的提问来源于stack exchange,提问作者Skazalasobaka
相关产品推荐
相关产品推荐

