APEX的树出错

本文探讨了在Oracle APEX中使用树形SQL查询遇到的问题及解决方案。原本在PL/SQL中正常运行的树形SQL,在APEX中无法正确显示,通过调整查询语句的结构,将WHERE子句外移至外部子查询,成功解决了问题,实现了树形数据的正确展示。

 select case when connect_by_isleaf = 1 then 0 when level = 1 then 1 else -1 end as status,
        level,
        zwkmzd_kmbh || ' '||zwkmzd_mc as title,
        'icon-tree-folder' as icon,
        zwkmzd_kmnm as value,
        zwkmzd_kmbh || ' '||zwkmzd_mc as tooltip,
         apex_util.prepare_url('f?p='||:app_id||':6001:'||:app_session||'::NO::P6001_ZWKMZD_KMNM:'||zwkmzd_kmnm) as link

   from  T_BHM_ZD_ZWKMZD
   where  zwkmzd_dwid=:P0_DWID and  zwkmzd_year=substr(:P0_DATE,1,4)
  start with ZWKMZD_SJKM is null
connect by prior zwkmzd_kmbh = ZWKMZD_SJKM
  order siblings by zwkmzd_kmbh

之前写的树的SQL 在pl/sql 运行的也没问题,在APEX里怎么都出不来。是因为加了where条件

改成:

 select case when connect_by_isleaf = 1 then 0 when level = 1 then 1 else -1 end as status,
        level,
        zwkmzd_kmbh || ' '||zwkmzd_mc as title,
        'icon-tree-folder' as icon,
        zwkmzd_kmnm as value,
        zwkmzd_kmbh || ' '||zwkmzd_mc as tooltip,
         apex_util.prepare_url('f?p='||:app_id||':6001:'||:app_session||'::NO::P6001_ZWKMZD_KMNM:'||zwkmzd_kmnm) as link

   from (select * from  T_BHM_ZD_ZWKMZD where
     zwkmzd_dwid=:P0_DWID and  zwkmzd_year=substr(:P0_DATE,1,4))
  start with ZWKMZD_SJKM is null
connect by prior zwkmzd_kmbh = ZWKMZD_SJKM
  order siblings by zwkmzd_kmbh

就好了

#!/usr/bin/env python # -*- coding: utf-8 -*- import os import re import sys import argparse import xlwt from collections import defaultdict # 分区名称映射表(前缀 → 友好名称) PARTITION_NAME_MAP = { '02_': 'system', '03_': 'vendor', '04_': 'product', '05_': 'odm', '06_': 'my_product', '07_': 'my_engineering', '08_': 'my_stock', '09_': 'my_heytap', '10_': 'my_company', '11_': 'my_carrier', '12_': 'my_region', '13_': 'my_preload', '14_': 'data', '15_': 'my_bigball', '16_': 'my_manifest', '17_system_dlkm': 'system_dlkm', '17_vendor_dlkm': 'vendor_dlkm', '17_cache': 'cache' } def parse_du_file(file_path): """解析du命令输出文件并转换为MB""" data = {} try: with open(file_path, 'r') as f: for line in f: if 'Permission denied' in line or 'No such file' in line or not line.strip(): continue match = re.match(r'(\d+\.?\d*)\s*([KMG]?)[Bb]?\s+(.*)', line.strip()) if match: size, unit, path = match.groups() size = float(size) # 单位转换到MB if unit == 'K': size = size / 1024.0 elif unit == '': size = size / (1024*1024.0) elif unit == 'M': pass elif unit == 'G': size = size * 1024.0 data[path] = round(size, 4) except IOError as e: print("警告: 无法读取文件 {}: {}".format(file_path, str(e))) return data def extract_file_prefix(filename): """提取文件前缀""" if filename.startswith('17_'): return filename.replace('.txt', '') match = re.match(r'^(\d+_)', filename) return match.group(1) if match else "other_" def is_main_partition_file(filename, prefix): """检查是否为主分区文件""" if prefix.startswith('17_'): return True expected_name = prefix + PARTITION_NAME_MAP[prefix] + ".txt" return filename == expected_name def generate_dual_report(folder1, folder2, output_xlsx): """生成双机对比报告""" folder1_name = os.path.basename(os.path.normpath(folder1)) folder2_name = os.path.basename(os.path.normpath(folder2)) for folder in [folder1, folder2]: if not os.path.exists(folder): print("错误: 目录不存在 - {}".format(folder)) return "目录 {} 不存在,请检查路径".format(folder) if not os.path.isdir(folder): print("错误: 路径不是目录 - {}".format(folder)) return "{} 不是有效目录".format(folder) # 初始化数据结构 machine1_main_data = {} machine2_main_data = {} machine1_all_files = defaultdict(dict) machine2_all_files = defaultdict(dict) # 收集数据 for folder_path, main_dict, all_dict in [ (folder1, machine1_main_data, machine1_all_files), (folder2, machine2_main_data, machine2_all_files) ]: print("处理目录: {}".format(folder_path)) try: for filename in os.listdir(folder_path): if not filename.endswith('.txt'): continue prefix = extract_file_prefix(filename) if prefix == '01_' or prefix not in PARTITION_NAME_MAP: continue file_path = os.path.join(folder_path, filename) partition_name = PARTITION_NAME_MAP[prefix] file_data = parse_du_file(file_path) all_dict[filename] = file_data if is_main_partition_file(filename, prefix): print("解析主分区文件: {}".format(file_path)) main_dict[prefix] = file_data except OSError as e: print("目录访问错误: {}".format(str(e))) return "无法访问目录 {}: {}".format(folder_path, str(e)) # 创建Excel工作簿 try: wb = xlwt.Workbook(encoding='utf-8') # ====== 修复:正确定义所有样式变量 ====== header_style = xlwt.easyxf('font: bold on') title_style = xlwt.easyxf('font: bold on, height 280; align: wrap on, vert centre') normal_style = xlwt.easyxf() added_style = xlwt.easyxf('pattern: pattern solid, fore_colour light_green;') removed_style = xlwt.easyxf('pattern: pattern solid, fore_colour rose;') summary_style = xlwt.easyxf('font: bold on, color blue;') wrap_style = xlwt.easyxf('align: wrap on, vert centre') # 修复:正确定义wrap_style # ====== 创建总览Sheet页 ====== ws_overview = wb.add_sheet('总览') print("创建总览Sheet页(仅主文件数据)") current_row = 0 # 写入总览标题 ws_overview.write_merge( current_row, current_row, 0, 5, "存储使用总览(仅主分区文件)", title_style ) current_row += 1 # 写入文件夹名称 ws_overview.write(current_row, 1, folder1_name, header_style) ws_overview.write(current_row, 2, folder2_name, header_style) current_row += 1 # 写入表头(增加备注列) headers = ['分区', '总大小(MB)', '总大小(MB)', '差值(MB)', '标记', '备注(增大TOP3)'] for col, header in enumerate(headers): ws_overview.write(current_row, col, header, header_style) current_row += 1 # 存储各分区汇总数据 overview_data = [] total_machine1 = 0.0 total_machine2 = 0.0 # 按分区顺序处理数据 for prefix in sorted(PARTITION_NAME_MAP.keys()): partition_name = PARTITION_NAME_MAP[prefix] # 跳过data分区 if partition_name == 'data': continue # 获取主文件数据 data1 = machine1_main_data.get(prefix, {}) data2 = machine2_main_data.get(prefix, {}) # 计算主文件总大小 partition_total1 = round(sum(data1.values()), 2) partition_total2 = round(sum(data2.values()), 2) diff = partition_total1 - partition_total2 # 更新总计 total_machine1 += partition_total1 total_machine2 += partition_total2 # 确定标记样式 if diff > 0: mark = "增加" style = added_style elif diff < 0: mark = "减少" style = removed_style else: mark = "无变化" style = normal_style # 计算分区中增大的TOP3路径 top_notes = [] if diff > 0: # 只在分区增大时计算TOP路径 path_diffs = [] all_paths = set(data1.keys()) | set(data2.keys()) for path in all_paths: size1 = data1.get(path, 0.0) size2 = data2.get(path, 0.0) path_diff = size1 - size2 if path_diff > 0: # 只记录增大的路径 path_diffs.append((path, path_diff)) # 按增大值降序排序,取TOP3 path_diffs.sort(key=lambda x: x[1], reverse=True) for i, (path, diff_val) in enumerate(path_diffs[:3]): # 截断过长的路径名 if len(path) > 50: path = "..." + path[-47:] top_notes.append("{}. {}: +{:.2f}MB".format(i+1, path, diff_val)) # 保存分区数据 overview_data.append({ 'name': partition_name, 'machine1': partition_total1, 'machine2': partition_total2, 'diff': diff, 'style': style, 'mark': mark, 'notes': "\n".join(top_notes) if top_notes else "无显著增大路径" }) # 写入行数据到总览页(增加备注列) ws_overview.write(current_row, 0, partition_name, style) ws_overview.write(current_row, 1, partition_total1, style) ws_overview.write(current_row, 2, partition_total2, style) ws_overview.write(current_row, 3, diff, style) ws_overview.write(current_row, 4, mark, style) ws_overview.write(current_row, 5, overview_data[-1]['notes'], wrap_style) # 使用已定义的wrap_style current_row += 1 # 添加空行 current_row += 1 # 写入总计行 total_diff = total_machine1 - total_machine2 if total_diff > 0: total_mark = "总增加" total_style = added_style elif total_diff < 0: total_mark = "总减少" total_style = removed_style else: total_mark = "无变化" total_style = normal_style ws_overview.write(current_row, 0, "总计", header_style) ws_overview.write(current_row, 1, total_machine1, header_style) ws_overview.write(current_row, 2, total_machine2, header_style) ws_overview.write(current_row, 3, total_diff, header_style) ws_overview.write(current_row, 4, total_mark, header_style) ws_overview.write(current_row, 5, "", header_style) # 备注列留空 # 设置备注列宽度(100字符) ws_overview.col(5).width = 256 * 100 # ====== 为每个文件创建单独的Sheet页(保持不变) ====== # 获取所有唯一的文件名(两个文件夹的并集) all_filenames = sorted(set(machine1_all_files.keys()) | set(machine2_all_files.keys())) for filename in all_filenames: # 提取文件前缀 prefix = extract_file_prefix(filename) # 跳过无效前缀 if prefix not in PARTITION_NAME_MAP: continue # 获取分区名称 partition_name = PARTITION_NAME_MAP[prefix] # 创建Sheet页名称(文件名不带扩展名) sheet_name = filename.replace('.txt', '') if len(sheet_name) > 31: # Excel sheet名称长度限制 sheet_name = sheet_name[:31] # 创建Sheet页 ws = wb.add_sheet(sheet_name) print("创建文件Sheet页: {}".format(sheet_name)) # 当前行指针 current_row = 0 # 写入分区标题 title = "分区: {} - 文件: {}".format(partition_name, filename) ws.write_merge( current_row, current_row, 0, 5, title, title_style ) current_row += 1 # 写入文件夹名称 ws.write_merge(current_row, current_row, 0, 1, folder1_name, header_style) ws.write_merge(current_row, current_row, 2, 3, folder2_name, header_style) ws.write(current_row, 4, "差异(M)", header_style) ws.write(current_row, 5, "标记", header_style) current_row += 1 # 写入表头 headers = ['路径', '大小(M)', '路径', '大小(M)', '差异(M)', '标记'] for col, header in enumerate(headers): ws.write(current_row, col, header, header_style) current_row += 1 # 获取文件数据 data1 = machine1_all_files.get(filename, {}) data2 = machine2_all_files.get(filename, {}) # 获取所有路径(合并两个文件夹的路径) all_paths = sorted(set(data1.keys()) | set(data2.keys())) # 初始化变化统计数据 total_increase = 0.0 # 增大总和 total_decrease = 0.0 # 减小总和 total_added = 0.0 # 新增文件总和 total_removed = 0.0 # 去除文件总和 # 写入数据行 for path in all_paths: size1 = data1.get(path, 0.0) size2 = data2.get(path, 0.0) # 计算差值 diff = size1 - size2 # 确定标记和样式 if size1 == 0 and size2 > 0: mark = "除去" cell_style = removed_style total_removed += size2 elif size1 > 0 and size2 == 0: mark = "新增" cell_style = added_style total_added += size1 else: if diff > 0: mark = "增大" cell_style = added_style total_increase += diff elif diff < 0: mark = "减小" cell_style = removed_style total_decrease += abs(diff) else: mark = "相同" cell_style = normal_style # 写入行数据 # folder1列 if size1 > 0: ws.write(current_row, 0, path, cell_style) ws.write(current_row, 1, size1, cell_style) else: ws.write(current_row, 0, "", cell_style) ws.write(current_row, 1, "", cell_style) # folder2列 if size2 > 0: ws.write(current_row, 2, path, cell_style) ws.write(current_row, 3, size2, cell_style) else: ws.write(current_row, 2, "", cell_style) ws.write(current_row, 3, "", cell_style) # 差异和标记列 ws.write(current_row, 4, diff, cell_style) ws.write(current_row, 5, mark, cell_style) current_row += 1 # 添加文件汇总行 file_total1 = sum(data1.values()) file_total2 = sum(data2.values()) file_diff = file_total1 - file_total2 # 写入汇总行 ws.write(current_row, 0, "文件汇总", header_style) ws.write(current_row, 1, file_total1, header_style) ws.write(current_row, 2, "", header_style) ws.write(current_row, 3, file_total2, header_style) ws.write(current_row, 4, file_diff, header_style) ws.write(current_row, 5, "", header_style) current_row += 1 # 添加变化分类统计行 message = ( u"{partition_name}路径下: " u"减小{total_decrease:.2f}M " u"增大{total_increase:.2f}M " u"新增文件{total_added:.2f}M " u"减少文件{total_removed:.2f}M" ).format( partition_name=partition_name, total_decrease=total_decrease, total_increase=total_increase, total_added=total_added, total_removed=total_removed ) ws.write_merge( current_row, current_row, 0, 5, message, summary_style ) # 保存文件 wb.save(output_xlsx) return "对比报告已成功生成: {}".format(output_xlsx) except Exception as e: import traceback traceback.print_exc() return "生成Excel文件时出错: {}".format(str(e)) # 单机拆解模式保持不变 def generate_single_report(folder, output_xlsx): """单机拆解模式(保持不变)""" # ...(原有单机拆解模式实现)... if __name__ == "__main__": # 创建参数解析器 parser = argparse.ArgumentParser(description='存储空间分析工具') subparsers = parser.add_subparsers(dest='mode', help='运行模式') # 双机对比模式 dual_parser = subparsers.add_parser('dual', help='双机对比模式') dual_parser.add_argument('folder1', help='第一个文件夹路径') dual_parser.add_argument('folder2', help='第二个文件夹路径') dual_parser.add_argument('output', help='输出Excel文件路径') # 单机拆解模式 single_parser = subparsers.add_parser('single', help='单机拆解模式') single_parser.add_argument('folder', help='待分析文件夹路径') single_parser.add_argument('output', help='输出Excel文件路径') # 解析参数 args = parser.parse_args() if args.mode == 'dual': print("运行双机对比模式...") result = generate_dual_report(args.folder1, args.folder2, args.output) elif args.mode == 'single': print("运行单机拆解模式...") result = generate_single_report(args.folder, args.output) else: result = "错误:请选择 'dual' 或 'single' 模式" print(result)这是一个将du测试机和对比机拆解的脚本,解析脚本adb shell du -sh /system/* > 02_system.txt 2>&1 adb shell du /system/* > 02_system_xiangxi.txt 2>&1 adb shell du -sh /system/apex/* > 02_system_apex.txt 2>&1 adb shell du -sh /system/app/* > 02_system_app.txt 2>&1......
最新发布
10-28
<think>好的,我现在需要帮助用户解决在Anaconda中安装apex库时遇到的问题。根据用户提供的引用内容,有几个可能的解决方案可以尝试。首先,我需要整理这些引用中的信息,然后按照步骤给出清晰的指导。 首先,引用[3]提到,安装apex时遇到AttributeError,建议去GitHub的apex仓库查找相关issue。这说明用户应该先检查是否有已知的解决方案。其次,引用[4]指出在安装前需要安装CUDA并配置cpp_ext和cuda_ext环境变量,这可能涉及到正确安装依赖项。另外,引用[2]提到的ImportError可能与Pyramid库的版本有关,需要降级Pyramid到1.9.4版本。引用[1]则提到了通过运行python setup.py install来编译安装,这可能是标准安装步骤的一部分。 接下来,我需要将这些信息整合成一个步骤化的解决方案。首先,建议用户克隆仓库并确保环境满足CUDA和PyTorch的要求。然后,检查Pyramid的版本,必要时降级。接着,通过运行安装命令并处理可能的依赖问题。如果这些步骤失败,再建议用户参考GitHub上的issue。 需要注意的是,用户使用的是Anaconda,所以可能需要用conda安装某些依赖。此外,确保CUDA版本与PyTorch和apex兼容也很重要。如果用户遇到特定的错误信息,比如关于pyramid.session的导入错误,降级Pyramid应该是解决方案的一部分。 最后,生成相关问题时要涵盖安装依赖、错误排查、验证安装以及替代安装方法等方面,帮助用户全面了解可能遇到的问题和后续步骤。</think>根据报错类型和系统环境,以下是分步解决方案: $\boxed{安装步骤与解决方案}$ 1. **前置环境检查** - 确认已安装匹配的CUDA工具包(推荐11.3+) - 验证PyTorch版本与CUDA版本对应关系 ```bash conda list | grep torch # 查看已安装的PyTorch版本 nvcc --version # 查看CUDA编译器版本 ``` 2. **源码编译安装(推荐)** ```bash git clone https://github.com/NVIDIA/apex cd apex # 若报错涉及pyramid.session,先执行: pip install pyramid==1.9.4 # 解决ImportError的关键步骤[^2] # 编译安装 pip install -v --no-cache-dir --global-option="--cpp_ext" --global-option="--cuda_ext" ./ ``` 3. **替代安装方案** 若步骤2失败,尝试: ```bash # 禁用CUDA扩展 pip install -v --no-cache-dir ./ # 或使用开发模式 python setup.py develop ``` 4. **Windows系统特别处理**[^4] - 安装Visual Studio 2019+ 并勾选"C++桌面开发" - 配置CUDA_PATH环境变量指向安装目录 - 使用x64 Native Tools Command Prompt进行编译 $\boxed{验证安装}$ ```python import torch from apex import amp # 无报错则成功 print(amp.__version__) ``` $\boxed{常见错误处理}$ - **AttributeError: module 'torch.distributed'...** 升级PyTorch到1.9+版本:`conda install pytorch torchvision cudatoolkit=11.3 -c pytorch` - **ImportError: cannot import name...** 强制降级pyramid:`pip install pyramid==1.9.4 --force-reinstall` - **C++编译错误** 安装最新版C++编译工具链:`conda install -c conda-forge gxx_linux-64`
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值