You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Python pyrfc正确读取SAP BW InfoCube数据?

SAP BW InfoCube数据读取解析问题解决方案

问题描述

通过Python的pyrfc库调用ABAP函数RSDRI_INFOPROV_READ_RFC读取SAP BW InfoCube数据时,返回的E_T_RFCDATA字段存在格式混乱问题:字段顺序错乱、KPI数值丢失、乱码。SAP系统内需用RSDRI_DATA_UNWRAP结构化数据,但该函数非RFC函数无法远程调用,需Python端等价解析方案。

现有代码

import pyrfc
import pandas as pd
import pprint

from pyrfc import Connection, ABAPApplicationError, ABAPRuntimeError, LogonError, CommunicationError

ASHOST = "myashost"
SYSNR = "xx" 
CLIENT = 'xx'
USER = "my_user"
PASSWD = "mymdp"
lang= 'EN'

i_th_sfc = [
  {"CHANM": "/CPMB/WVDU6SJ",
   "CHAALIAS": "AUDITTRAIL",
   },
   {"CHANM": "/CPMB/WVD9OS5",
   "CHAALIAS": "TIME",
   },
   {"CHANM": "/CPMB/WVD9X7E",
   "CHAALIAS": "CONTRIBUTOR",
   },
    {"CHANM": "/CPMB/WVDYXDT",
   "CHAALIAS": "RUBRIC",
   }

] 

i_th_sfk = [
  {"KYFNM": "/CPMB/SDATA",
   "KYFALIAS" : "KPI",
   "AGGR" : "SUM"
},
]

conn = pyrfc.Connection(ashost=ASHOST, sysnr=SYSNR, client=CLIENT, user=USER, passwd=PASSWD, lang= lang)

result = conn.call("RSDRI_INFOPROV_READ_RFC",
  I_INFOPROV = "/CPMB/WVIKBIP"
  ,I_T_SFC = i_th_sfc
  ,I_T_SFK = i_th_sfk
  , I_MAXROWS = 2
)
pprint.pprint(result, width=100, compact=True)

解决方案

1. 理解E_T_RFCDATA结构

RSDRI_INFOPROV_READ_RFC返回的E_T_RFCDATA是扁平化字节流,每行数据按传入的特征(I_T_SFC)和关键值(I_T_SFK)定义顺序拼接,需根据字段长度、数据类型拆分解析。

2. Python端实现解析逻辑

步骤1:获取字段元数据

调用RSDRI_INFOPROV_METADATA_READ_RFC获取字段长度、类型等元数据,无需手动计算:

# 获取InfoCube元数据
metadata = conn.call("RSDRI_INFOPROV_METADATA_READ_RFC",
    I_INFOPROV="/CPMB/WVIKBIP",
    I_T_SFC=i_th_sfc,
    I_T_SFK=i_th_sfk
)

# 提取特征和关键值的元数据
sfc_metadata = metadata["E_T_SFC"]
sfk_metadata = metadata["E_T_SFK"]

步骤2:整理字段规则

按特征、关键值的顺序,整理每个字段的别名、长度和类型:

field_specs = []
# 添加特征字段规则
for field in sfc_metadata:
    field_specs.append({
        "name": field["CHAALIAS"],
        "length": field["INTLEN"],
        "type": field["INTTYPE"]
    })
# 添加关键值字段规则
for field in sfk_metadata:
    field_specs.append({
        "name": field["KYFALIAS"],
        "length": field["INTLEN"],
        "type": field["INTTYPE"]
    })

步骤3:拆分并转换数据

遍历E_T_RFCDATA的每行数据,按字段规则拆分并转换数据类型:

parsed_data = []
for row in result["E_T_RFCDATA"]:
    raw_str = row["DATA"]
    parsed_row = {}
    current_pos = 0
    for spec in field_specs:
        # 截取对应长度的字符串
        field_value = raw_str[current_pos:current_pos + spec["length"]].strip()
        # 根据类型转换数据
        if spec["type"] in ["N", "F"]:
            parsed_row[spec["name"]] = float(field_value) if spec["type"] == "F" else int(field_value) if field_value else None
        else:
            parsed_row[spec["name"]] = field_value
        current_pos += spec["length"]
    parsed_data.append(parsed_row)

# 转换为DataFrame便于分析
df = pd.DataFrame(parsed_data)
print(df)

3. 解决乱码问题

乱码源于编码不匹配,可通过以下两种方式处理:

  • 连接时指定编码:
    conn = pyrfc.Connection(ashost=ASHOST, sysnr=SYSNR, client=CLIENT, user=USER, passwd=PASSWD, lang=lang, codepage="UTF-8")
    
  • 解析时转换编码:
    field_value = raw_str[current_pos:current_pos + spec["length"]].decode("ISO-8859-1").encode("UTF-8").strip()
    

4. 自定义RFC函数替代方案

若解析逻辑复杂,可在SAP系统创建自定义RFC函数,内部调用RSDRI_INFOPROV_READ_RFC和RSDRI_DATA_UNWRAP,直接返回结构化数据给Python,简化端侧解析。

内容的提问来源于stack exchange,提问作者dayidir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 21:45:19