用Python+PyRFC批量处理SAP数据?一个读取SPFLI表的脚本带你快速上手

Linux文本编辑器Vim操作命令汇总! vim编辑器无疑是每个开发者都必须掌握的,通常在Linux的服务器操作文件内容都是需要使用到它的。但是在使用时能够记住的vim命令又是少之又少,如果是专业运维人员的话可能就比较熟悉,但是我们开发人员一般只有在服务器部署、日志查看等场景才能使用到。所以就经常容易忘记,于是今天在这里将Vim使用到的命令和操作都进行了一个汇总,以免大家在使用的过程中遇到一些生僻的命令就需要去查资料。 阅读详情

Python+PyRFC实战:高效读取SAP航空数据表的完整指南

引言

在传统企业IT架构中,SAP系统往往承载着核心业务数据,但如何将这些数据高效提取并用于现代数据分析一直是开发者的痛点。想象一下,当你需要从SAP系统中获取航班时刻表数据进行分析时,传统方式可能需要等待IT部门导出报表,或者编写复杂的ABAP程序。而今天,我们将展示如何用Python生态中的PyRFC工具包,直接与SAP系统建立桥梁,实现数据的实时获取和处理。

PyRFC作为SAP官方推荐的Python接口工具,已经发展到2.x版本,稳定性和功能都有了显著提升。不同于早期版本对Unicode支持不足的问题,现在的PyRFC可以完美处理多语言数据,特别是对于国际化的航空数据(如包含中文机场名称的情况)也能游刃有余。

1. 环境准备与SDK配置

1.1 安装SAP NW RFC SDK

PyRFC本质上是SAP NW RFC SDK的Python封装,因此需要先安装这个基础开发包。最新版本的SDK可以从SAP官网获取(需要SAP账号权限),也可以从PyRFC项目的GitHub仓库找到兼容版本。

安装完成后,需要配置两个关键环境变量:

# Windows系统示例
set SAPNWRFC_HOME=C:\path_to_sdk\nwrfcsdk
set PATH=%PATH%;%SAPNWRFC_HOME%\lib;%SAPNWRFC_HOME%\bin

验证安装是否成功:

import pyrfc
print(pyrfc.get_nwrfcsdk_version())  # 应显示类似'7200.0.28'的版本号

1.2 安装PyRFC包

推荐使用pip安装最新稳定版:

pip install pynwrfc

如果遇到版本冲突,可以尝试指定版本:

pip install pyrfc==2.1.0

2. 建立SAP连接基础

2.1 连接参数配置

连接SAP系统需要以下核心参数:

conn_params = {
    "ashost": "sap.example.com",  # SAP应用服务器地址
    "sysnr": "00",               # 系统编号
    "client": "100",             # 客户端编号
    "user": "developer",         # 用户名
    "passwd": "secure_password", # 密码
    "lang": "EN"                 # 语言代码
}

重要提示 :实际项目中,建议将敏感信息存储在环境变量或配置文件中,不要硬编码在脚本里。

2.2 连接测试与错误处理

稳健的连接代码应该包含错误处理:

import pyrfc
from pyrfc import ConnectionError

try:
    conn = pyrfc.Connection(**conn_params)
    print("连接成功!SAP系统信息:", conn.get_system_info())
except ConnectionError as e:
    print(f"连接失败: {e}")
finally:
    conn.close() if 'conn' in locals() else None

3. 读取SPFLI航空数据表示例

3.1 理解SPFLI表结构

SPFLI是SAP自带的示例航班数据表,包含以下关键字段:

字段名 描述 数据类型
CARRID 航空公司代码 CHAR(3)
CONNID 航班连接号 NUMC(4)
COUNTRYFR 出发国家 CHAR(3)
CITYFROM 出发城市 CHAR(20)
AIRPFROM 出发机场 CHAR(3)
COUNTRYTO 到达国家 CHAR(3)
CITYTO 到达城市 CHAR(20)
AIRPTO 到达机场 CHAR(3)

3.2 使用RFC_READ_TABLE函数

以下是读取SPFLI表的完整示例:

def read_spfli_data(conn_params, country_filter=None):
    conn = pyrfc.Connection(**conn_params)
    
    # 构建查询选项
    options = []
    if country_filter:
        options.append({"TEXT": f"COUNTRYFR EQ '{country_filter}'"})
    
    # 指定需要获取的字段
    fields = [
        {"FIELDNAME": "CARRID"},
        {"FIELDNAME": "CONNID"},
        {"FIELDNAME": "COUNTRYFR"},
        {"FIELDNAME": "CITYFROM"},
        {"FIELDNAME": "AIRPFROM"},
        {"FIELDNAME": "COUNTRYTO"},
        {"FIELDNAME": "CITYTO"},
        {"FIELDNAME": "AIRPTO"}
    ]
    
    result = conn.call(
        'RFC_READ_TABLE',
        QUERY_TABLE="SPFLI",
        DELIMITER="|",
        OPTIONS=options,
        FIELDS=fields
    )
    
    # 处理返回数据
    data = []
    for row in result['DATA']:
        values = row['WA'].split('|')
        data.append(dict(zip([f['FIELDNAME'] for f in result['FIELDS']], values)))
    
    conn.close()
    return data

3.3 数据转换与增强

原始数据返回格式较为简单,我们可以用pandas进行增强处理:

import pandas as pd

def get_flight_data_as_dataframe(conn_params, country=None):
    raw_data = read_spfli_data(conn_params, country)
    df = pd.DataFrame(raw_data)
    
    # 类型转换
    df['CONNID'] = df['CONNID'].astype(int)
    
    # 添加计算列
    df['ROUTE'] = df['AIRPFROM'] + '-' + df['AIRPTO']
    
    return df

4. 高级应用与性能优化

4.1 批量处理大量数据

当处理大型表时,需要分批次获取数据:

def read_large_table_in_batches(conn_params, table_name, batch_size=10000):
    conn = pyrfc.Connection(**conn_params)
    row_skip = 0
    all_data = []
    
    while True:
        result = conn.call(
            'RFC_READ_TABLE',
            QUERY_TABLE=table_name,
            ROWCOUNT=batch_size,
            ROWSKIP=row_skip
        )
        
        if not result['DATA']:
            break
            
        # 处理数据...
        all_data.extend(process_data(result))
        
        row_skip += batch_size
    
    conn.close()
    return all_data

4.2 并行处理技术

对于需要处理多个表或复杂查询的情况,可以使用Python的并发特性:

from concurrent.futures import ThreadPoolExecutor

def parallel_read_tables(conn_params, table_list):
    with ThreadPoolExecutor(max_workers=4) as executor:
        futures = {
            executor.submit(read_spfli_data, conn_params, table): table
            for table in table_list
        }
        
        results = {}
        for future in concurrent.futures.as_completed(futures):
            table_name = futures[future]
            results[table_name] = future.result()
    
    return results

4.3 数据缓存策略

频繁读取相同数据时,考虑实现缓存机制:

from functools import lru_cache
import hashlib

@lru_cache(maxsize=32)
def cached_read_table(conn_params, table_name, query=None):
    params_hash = hashlib.md5(str(conn_params).encode()).hexdigest()
    cache_key = f"{params_hash}_{table_name}_{query}"
    
    # 实际读取逻辑...
    return read_table_data(conn_params, table_name, query)

5. 实际业务场景应用

5.1 航班数据分析案例

假设我们需要分析某航空公司的航线网络:

def analyze_airline_routes(df):
    # 计算各航空公司航线数量
    route_counts = df.groupby('CARRID')['ROUTE'].nunique()
    
    # 找出枢纽机场(连接最多的机场)
    hub_airports = pd.concat([
        df['AIRPFROM'].value_counts(),
        df['AIRPTO'].value_counts()
    ]).groupby(level=0).sum().sort_values(ascending=False)
    
    # 国际航线占比
    international = (df['COUNTRYFR'] != df['COUNTRYTO']).mean()
    
    return {
        'route_counts': route_counts,
        'hub_airports': hub_airports,
        'international_ratio': international
    }

5.2 数据可视化集成

结合matplotlib或Plotly进行可视化:

import plotly.express as px

def visualize_routes(df):
    fig = px.scatter_geo(df,
                        lat='LATITUDE',  # 假设已添加经纬度数据
                        lon='LONGITUDE',
                        hover_name='CITYFROM',
                        color='CARRID',
                        title='航空公司航线网络')
    fig.show()

5.3 异常检测与数据质量检查

def data_quality_check(df):
    # 检查缺失值
    missing_values = df.isnull().sum()
    
    # 异常值检测
    unusual_airports = df[~df['AIRPFROM'].str.match('^[A-Z]{3}$')]
    
    # 时间合理性检查(假设有飞行时间字段)
    if 'FLIGHT_TIME' in df:
        unreasonable_time = df[df['FLIGHT_TIME'] > 20]  # 超过20小时的航班
        
    return {
        'missing_values': missing_values,
        'unusual_airports': unusual_airports,
        'unreasonable_time': unreasonable_time if 'FLIGHT_TIME' in df else None
    }

6. 安全与最佳实践

6.1 连接安全管理

from cryptography.fernet import Fernet
import os

class SAPConnectionManager:
    def __init__(self, key_file='sap_key.key'):
        self.key = self._get_or_create_key(key_file)
        self.cipher = Fernet(self.key)
    
    def _get_or_create_key(self, key_file):
        if os.path.exists(key_file):
            with open(key_file, 'rb') as f:
                return f.read()
        else:
            key = Fernet.generate_key()
            with open(key_file, 'wb') as f:
                f.write(key)
            return key
    
    def encrypt_credentials(self, plain_params):
        encrypted = {
            k: self.cipher.encrypt(v.encode()).decode() 
            for k, v in plain_params.items()
        }
        return encrypted
    
    def decrypt_credentials(self, encrypted_params):
        return {
            k: self.cipher.decrypt(v.encode()).decode()
            for k, v in encrypted_params.items()
        }

6.2 性能监控与日志

import logging
import time
from contextlib import contextmanager

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger('sap_rfc')

@contextmanager
def log_rfc_call(func_name):
    start_time = time.time()
    logger.info(f"开始调用RFC函数: {func_name}")
    try:
        yield
    except Exception as e:
        logger.error(f"RFC调用失败: {func_name}, 错误: {str(e)}")
        raise
    finally:
        duration = time.time() - start_time
        logger.info(f"RFC调用完成: {func_name}, 耗时: {duration:.2f}秒")

# 使用示例
with log_rfc_call('RFC_READ_TABLE'):
    result = conn.call('RFC_READ_TABLE', ...)

6.3 单元测试策略

import unittest
from unittest.mock import MagicMock

class TestSAPRFC(unittest.TestCase):
    def setUp(self):
        self.mock_conn = MagicMock()
        self.test_data = {
            'DATA': [{'WA': 'AA|100|US|NEW YORK|JFK|GB|LONDON|LHR'}],
            'FIELDS': [{'FIELDNAME': 'CARRID'}, ...]
        }
        
    def test_read_spfli_data(self):
        self.mock_conn.call.return_value = self.test_data
        result = read_spfli_data(self.mock_conn)
        self.assertEqual(len(result), 1)
        self.assertEqual(result[0]['CARRID'], 'AA')
        
    def test_empty_result(self):
        self.mock_conn.call.return_value = {'DATA': []}
        result = read_spfli_data(self.mock_conn)
        self.assertEqual(len(result), 0)
如何编写 Python 代码消费 SAP ABAP 系统的 Remote Enabled Function Module PyRFC 是一个 Python 库,为 SAP NetWeaver RFC(Remote Function Call)库提供绑定,使开发者能够通过 Python 调用 ABAP 模块,或从 ABAP 调用 Python 模块。它封装了现有的 SAP NetWeaver RFC 库,利用 Cython 重写,旨在为 Python 与 SAP 系统之间的通信提供简洁而高效的接口。 阅读详情

相关推荐

vim操作大全

本章提供足够的信息使你用够使用 Vim 来做基本的编辑。花些时间去练习这些命令,这是后面的知识的基础。里边的东西通俗易懂,还有小例子跟进,绝对是vim学习和使用的有力工具

超详Linux之vim命令大全

Linux之超强vim编辑器最强使用

qq_53111132的博客 1万+

vim命令操作大全

本图片包含大量的常用vim使用命令和操作,而且对所使用的命令进行了分类,方便查阅

Linux基础-vim命令详解(理论+实战)

本文主要内容为vim命令介绍、命令模式介绍、vim操作、vim命令可视化模式及用法

qq_27815483的博客 4万+

vi常用操作指令

vi常用操作指令~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Linux文件编辑命令vi详细整理(总结)

刚接触Linux,前几天申请了个免费体验的阿里云服务器,选择的是Ubuntu系统,配置jdk环境变量的时候需要编辑文件。 vi命令编辑文件,百度了一下,很多回答不是很全面,因此编辑文件话了一些时间。 这里博主整理了一下,分享给大家。 一、vi编辑器有3种基本工作模式 首先需要知道vi编辑器有3种基本工作模式,分别是:命令模式、文本输入模式、和末行模式。 第一:命令行模式:该模式是进入vi编辑器后的默认模式。任何时候,不管用户处于何种模式,按下ESC键即可进入命令模式。在该模式下,用户可以输入vi命令,用户管理自己的文档。此时从键盘上输入的任何字符都被当作编辑命令来解释。若输入的字符是合法的vi

【Linux】vim指令大全,收藏这篇就够了

本篇博客讲解vim的各种指令。

luhaoran814的博客 1万+

Keil开发中CMSIS Driver API缺失问题的排查与解决

本文详细解析Keil开发中CMSIS Driver API缺失问题的根源与解决方案。针对版本不匹配、安装不完整等常见原因,提供在线与离线安装的对比及详细排查步骤,重点涵盖版本兼容性分析与项目配置验证,帮助开发者彻底解决API缺失错误并预防问题复发。

rust6ferris的博客 550

Linux之Vim常用命令

文章目录1 普通模式1.1 移动光标1.2 复制1.3 剪切1.4 删除1.5 粘贴1.6 替换和撤销2 命令模式2.1 退出编辑器2.2 调整文本2.3 查找字符串 1 普通模式 以下命令请在普通模式执行 1.1 移动光标 j:向下 20j: 向下移动 20 行 k:向上 h:向左 l:向右 0:到行首 ^:到行首第一个字符,如果前面有空格的话 $:到行尾 gg:快速到文件头 G:快速到文件尾...

上善若泪 2万+

从0入门LocoTrack:6倍加速的SLAM追踪新范式实战指南

传统点追踪方法(如CorrTracker、TAPIR)在处理大规模场景或实时任务时,要么精度不足,要么速度太慢。而LocoTrack通过“局部4D相关性”和“Transformer全局关联”的创新设计,实现了精度与速度的双重突破速度:比现有SOTA方法快6倍,吞吐量高达数万点/秒;精度:在Kinetics、DAVIS等数据集上,定位误差显著低于传统方法;鲁棒性:能应对低纹理、动态场景等复杂环境,这是传统方法的“噩梦场景”。

m0_71589036的博客 95

多算法数据预测——BP、ELM、LSTM、BiLSTM和SAELSTM,附Matlab源码

本文将为大家介绍基于BP、ELM、LSTM、BiLSTM和SAELSTM多种算法的数据预测,并提供相应的Matlab源码。SAELSTM算法是一种结合自动编码器和LSTM神经网络的深度学习方法,用于时间序列数据预测。ELM算法是一种单层前向神经网络,在单次训练过程中直接产生输出权重,从而具有快速学习和良好推广性能。多算法数据预测——BP、ELM、LSTM、BiLSTM和SAELSTM,附Matlab源码。总体来看,采用多种算法进行数据预测可以提高预测准确率,并可根据不同场景选择适合的算法。

qq_39605374的博客 864

SAP 接口编程 - PyRFC

之前我有比较系统地讲解过 SAP 接口编程,但没有使用 Python 语言的,主要是因为没有一个合适的 package。之前偶见几篇介绍 PyRFC 的文章,因为对 unicode 的支持实在不敢恭维,没有任何尝试的欲望。现在 PyRFC 已经到了 2.1 版本(https://pypi.org/project/pynwrfc/),有了质的飞跃,代码在 Github 上开源(https://github.com/SAP/PyRFC),可以作为 SAP 接口编程的一个选择了。 安装 安装 SAP NW RFC

王敏的专栏 6282

计算电磁学(三)有限差分方法

有限差分方法(FDM)是一种数值处理方法,通过将偏微分方程变换为一组代数方程,通过求解代数方程组来得到原边值问题的近似值。由于有限差分法非常简单,所以也特别的稳定高效。其中时域有限差分方法(FDTD)是电磁分析中的常用方法。在计算电磁学中,常用有限差分方法(finite difference equations)来替代微分方程。一个有限差分法通常包括三个步骤将求解域划分网格用有限差分方程逼近给定的微分方程求解在给定边界条件和初始状态下的方程常用的网格模型方阵斜方阵三角阵圆形阵。

CCC_B的博客 1639

从PyRFC到原生C:SAP接口开发的性能与维护性权衡

本文深入探讨了SAP接口开发中PyRFC与原生C语言(NW RFC SDK)的性能与维护性权衡。通过实测数据对比,C语言在响应时间、内存占用和并发处理上优势明显,而PyRFC则显著提升开发效率。文章为开发者提供了基于不同场景的技术选型建议,并分析了未来技术演进方向,帮助企业在SAP系统集成中做出最优决策。

yolo5detector的博客 368

【WRF工具】WRF 模型输出可视化工具 RIP4

【WRF工具】WRF 模型输出可视化工具 RIP4

WW、forever的博客 1594

Scratch全攻略:从入门到实践的编程之旅

Scratch 是一款由麻省理工学院(MIT)开发的图形化编程工具 ,它诞生的初衷是为了让编程教育更加普及,尤其是让孩子们能够轻松接触和学习编程。与传统的基于文本代码的编程方式不同,Scratch 通过将编程指令以图形化的积木形式呈现,极大地降低了编程的门槛,让编程变得如同搭积木一样简单有趣。

邓邓子的博客 1万+

用Python+PyRFC玩转SAP数据:5分钟搞定RFC_READ_TABLE查询与结果美化

本文详细介绍了如何利用Python和PyRFC实现与SAP系统的无缝对接,特别聚焦于RFC_READ_TABLE函数的实战应用。通过环境配置、函数解析、数据查询与美化等步骤,帮助开发者快速掌握SAP数据查询与可视化技术,提升企业级数据处理效率。

weixin_33690963的博客 329

YOLOv5源码逐行超详细注释与解读(5)——配置文件yolov5s.yaml

全网最详细的YOLOv5源码解读之配置文件yaml。逐行注释,逐句讲解,一文带你了解yaml。小白必看!

路人贾的博客 1万+

Linux的vim编辑命令

https://www.cnblogs.com/xiaolehong/p/15915733.html

qq_49367496的博客 2527

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Linux Vim文本编辑器-Vim常用命令

Vim文本编辑器使用与常用命令,外加使用技巧介绍

m0_71673753的博客 7569

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

【Linux系统编程】Linux编辑器——vim

详细介绍Linux中的编辑器——vim的使用

m0_70980326的博客 6351

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Linux之vim命令大全

在vimrc中添加set fileencoding=ucs-bom,utf-8,cp936,vim会根据要打开的文件选择合适的编码。一个小技巧:按8,再按i,进入插入模式,输入=, 按esc进入命令模式,就会出现8个=。(CTRL-W s 或 CTRL-W CTRL-S) 注意如果在终端下,CTRL-S可能会冻结终端,请按CTRL-Q继续。如 :Gtags -P .h$ 显示所有头文件, :Gtags -P /vm/ 显示vm目录下的文件。如果想跳转到更老的位置,可以按C-o,跳转到更新的位置用C-i。

weixin_71405027的博客 3761

Linux常用命令汇总(含vim)

常用的linux系统操作命令,vim编辑器常用命令

qq_43323210的博客 1928

【Linux】-Linux下的编辑器Vim的模式命令大全及其自主配置方法

以上就是关于vim的使用及配置,有些东西不是很具体,大家可以多做扩展。

m0_71503225的博客 5031

Vim的最全命令总结(Linux)

查找当前光标对应的单词然后输入,并可通过 n 或 N 进行上一个或下一个的匹配。与字符串之间不要有空格,因为该空格也会被认为是查询的字符串。vim有四种模式: 普通模式、输入模式、命令模式、可视模式。, 回车,并可通过 n 或 N 进行上一个或下一个的匹配。打开文件直接进入的是普通模式。拷贝该单词, 然后输入。

2301_79695159的博客 1万+
上一篇: 基于树莓派的智能镜子:物联网环境监测系统全栈开发实践
下一篇: 别再为相干信号头疼了!手把手教你用MATLAB实现前后向空间平滑MUSIC算法
weixin_33728708
博客等级 码龄11年 5472粉丝 1452原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值