SAP ERP のデータをRFC経由でPython+Pandasに読み込む

ERPというか、ABAPインスタンスのデータをPandasに取り込む方法です。

実は昔、以下の記事で、Pythonからの接続については書いたのですが、その時から時間経ったのでPythonからの接続と、Pandasにデータ読み込むところまで進めてみました。

PythonからSAP処理を呼び出してみる - YOMON8.NET

前準備

作業ディレクトリ作成

作業ディレクトリ作成します。名前は適当です。

$ mkdir sap_pandas
$ cd sap_pandas

SAP NW RFC SDKダウンロード

SAPにPythonから接続するためにはSAP NW RFC SDKが必要です。(※ Sユーザ必要です)

以下の情報からダウンロードします。

SAP NetWeaver Remote Function Call (RFC) Software Development Kit (SDK)

2573790 - Installation, Support and Availability of the SAP NetWeaver RFC Library 7.50

ダウンロード画面の例です。WSLで作業しているのでLinux用のSDKをダウンロードしてきます。

作業ディレクトリに展開しておきます。

$ mv /your/download/path/nwrfc750P_5-70002752.zip .
$ unzip nwrfc750P_5-70002752.zip
$ ls nwrfcsdk/
bin  demo  doc  include  lib

PyRFCインストール

この手順ができるのは、こちらのGithubのリポジトリのおかげです。いつの間にかStarが285個もついていたり、需要あるんだろうなと感想です。作者やコミッターの方々、ありがとうございます!

github.com

PyRFCコンパイル準備

PyPiからインストールとはいかないので、コンパイルする必要があります。

作業ディレクトリに移動して、 SAPNWRFC_HOME という環境変数を定義します。ここでは、先ほど展開したSAP NW RFC SDKのディレクトリを指定します。

$ cd sap_pandas
$ export SAPNWRFC_HOME=$(pwd)/nwrfcsdk

コンパイル前提モジュールのインストール

以下のようにcythonとpytestを入れておきます。

ここでvenv環境に移行したので、以下はpython3もpythonと書きます。ちなみにMakefile内の処理はpython3と書かれているので、この方法だとmakeコマンドは動かないです。

$ python3 -m venv venv
$ . venv/bin/activate
(venv) $
(venv) $ pip install cython pytest

PyRFCコンパイル実行

Githubからリポジトリをクローンしてきて、コンパイルします。2020/02/23時点では2.0.1が最新でしたが、1.9.99という枯れてそうなバージョン使いました。

$ git clone https://github.com/SAP/PyRFC.git
$ cd PyRFC
$ git checkout -f 1.9.99
$ git branch
* (HEAD detached at 1.9.99)
  master
$ python setup.py bdist_wheel
Compiling src/pyrfc/_pyrfc.pyx because it changed.
[1/1] Cythonizing src/pyrfc/_pyrfc.pyx
#---省略

dist配下にコンパイルされたパッケージができます。

$ ls dist/
pyrfc-1.9.99-cp36-cp36m-linux_x86_64.whl

これを指定してインストールします。

$ pip install dist/pyrfc-1.9.99-cp36-cp36m-linux_x86_64.whl
Processing ./dist/pyrfc-1.9.99-cp36-cp36m-linux_x86_64.whl
Requirement already satisfied: setuptools in /home/yomon8/.virtualenvs/sappandas/lib/python3.6/site-packages (from pyrfc==1.9.99) (45.2.0)
Installing collected packages: pyrfc
Successfully installed pyrfc-1.9.99

PythonからABAPインスタンスへの接続

PyRFCがインストールできたので、SAPに接続してみます。

PandasとJupyterインストール

その前に、開発用に使うJupyter NotebookとPandasインストールしておきます。

pip install jupyter pandas

Jupyterから接続テスト

共有ライブラリへのパスを通してからJupyter Notebookを実行してみます。この際に共有ライブラリへのパスを設定してあげます。

$ export LD_LIBRARY_PATH=${SAPNWRFC_HOME}/lib
$ jupyter notebook

まずはREADMEにあるのと同じように、STFC_CONNECTIONで接続確認までできました。ちなみに、接続先はわかる人にはわかるとおり、ERP 6.0 EHP8のIDESです。

from pyrfc import Connection
conn = Connection(ashost='10.0.0.1', sysnr='00', client='100', user='me', passwd='secret')

Pandasにデータ読み込み

やっと下準備が完了しました。ついにPandasにデータを読み込みます。気の利いたシナリオも作れないので、とりあえず、元BASISらしく(?)、このCVERSのテーブルをPandasに読み込んでみようと思います。

わかりやすい、 RFC_READ_TABLEという汎用モジュールを実行します。 ※こちらのモジュールは色々と制限があるのでご注意ください。

https://launchpad.support.sap.com/#/notes/382318

ざっくりコードですが、書いておきます。

import pandas as pd
from pyrfc import Connection

# 汎用モジュールの結果をパースする処理
def parse_table(raw_data,fields):
    for raw_row in raw_data:        
        row = []
        for f in fields:
            offset = int(f['OFFSET'])
            length = int(f['LENGTH'])
            row += [raw_row['WA'][offset:offset+length]]
        yield row

# SAPとの接続
conn = Connection(
    ashost='YOUR_SAP_HOST', 
    sysnr='00', 
    client='000', 
    user='idadmin', 
    passwd='ides123',
)

# 汎用モジュールRFC_READ_TABLEを実行
cvers_tab = conn.call('RFC_READ_TABLE', QUERY_TABLE='CVERS')

# DataFrame作成に必要な情報を準備
raw_data = cvers_tab['DATA']
fields = cvers_tab['FIELDS']
columns = [c['FIELDNAME'] for c in fields]
parsed_rows = parse_table(raw_data,fields)

# DataFrame作成
df = pd.DataFrame(data=parsed_rows,columns=columns)

# ↓DataFrameを使った処理

実際に読み込んだ画面です。

まずは、RFC_READ_TABLE で読み込んだところ

次に、Pandasまで読み込んだところ

SAP ERP -> Pandasをやりたくて書いてきました。使うには検討しないといけないこと、色々ありそうですが、まずは基本というところで。