記事
Megumi Kakechi · 2022年4月17日 4m read

Embedded Python で Excel のデータを IRIS グローバルに格納する方法

InterSystems IRIS 2021.2 のバージョンより、Embedded Python を使用できるようになりました。
Embedded Python については、「Embedded Pythonを簡単にご紹介します」の記事をぜひご覧ください。

こちらでは、Embedded Python を使用して Excel のデータを IRIS グローバルに出力する方法をご紹介します。

最初に、irispip コマンドで必要なライブラリをインストールします。
今回は、pandas、xlrd、openpyxl の3つのライブラリをインストールします。

>cd C:\InterSystems\IRIS\bin
C:\InterSystems\IRIS\bin>irispip install --target C:\InterSystems\IRIS\mgr\python pandas
C:\InterSystems\IRIS\bin>irispip install --target C:\InterSystems\IRIS\mgr\python xlrd
C:\InterSystems\IRIS\bin>irispip install --target C:\InterSystems\IRIS\mgr\python openpyxl


Excel ファイルは次のような test.xslx を用意します。

Name Age Address
佐藤 50 東京
加藤 40 大阪
伊藤 30 京都


VSCode または IRISスタジオで次のようなクラスを作成します。
メソッドの宣言部に [ Language = Python ] と指定することで、クラスのメソッドに直接 Pythonコードを書くことができます。

Class User.PythonTest Extends %Persistent
{

ClassMethod fromPythonString(in As %String)
{
 set ^ISJ($increment(^ISJ))=$LISTFROMSTRING(in,",")
}

ClassMethod PythonPrint(fname as %String) [ Language = python ]
{
    import iris
    import pandas
    df=pandas.read_excel(fname, header=None)
    for key,row in df.iterrows():
     moji=",".join(list(map(str, row)))
     #iris.cls('User.PythonTest').fromPythonString(moji)
     iris.cls(__name__).fromPythonString(moji)
}
}


上の IRIS クラスでは、以下のような処理を行っています。

① Python プログラム(PythonPrint)で、拡張子「.xlsx」のエクセルファイルを pandas データフレームに読み込む
  ↓
② Dataframe のデータを行単位で読み込み、iris モジュールの cls() メソッドで文字列をグローバルに格納するクラスメソッド(fromPythonString)に渡す
  ↓
③ クラスメソッドの中で $LISTFROMSTRING() を使用して ^ISJ グローバルにセットする。
 

 

IRISターミナルから正しく実行できているかを確認します。

USER>kill ^ISJ
 
USER>do ##class(User.PythonTest).PythonPrint("c:\temp\test.xlsx")
 
USER>zw ^ISJ
^ISJ=4
^ISJ(1)=$lb("Name","Age","Address")
^ISJ(2)=$lb("佐藤","50","東京")
^ISJ(3)=$lb("加藤","40","大阪")
^ISJ(4)=$lb("伊藤","30","京都")
 
USER>


Pythonプログラムのデバッグを行いたい場合は、 Python シェルに切り替えて確認することができます。

USER>kill ^ISJ
 
USER>do ##class(%SYS.Python).Shell()
 
Python 3.9.5 (default, Jan 31 2022, 17:55:36) [MSC v.1927 64 bit (AMD64)] on win32
Type quit() or Ctrl-D to exit this shell.
>>> import iris
>>> import pandas
>>> df=pandas.read_excel('c:\\temp\\test.xlsx', header=None)
>>> for key,row in df.iterrows():
...  moji=','.join(list(map(str, row)))
...  iris.cls('User.PythonTest').fromPythonString(moji)
... 
>>> exit()
 
USER>zwrite ^ISJ
^ISJ=4
^ISJ(1)=$lb("Name","Age","Address")
^ISJ(2)=$lb("佐藤","50","東京")
^ISJ(3)=$lb("加藤","40","大阪")
^ISJ(4)=$lb("伊藤","30","京都")
 
USER>

 

上のサンプルでは、IRISのクラスメソッドを呼び出して操作していますが、Python プログラムで直接 IRIS のグローバルに書き込むことも可能です。
その場合は、iris.gref("^ISJ") のように、^ISJ へのグローバル参照を取得して書き出しが行えます。
詳細は以下のドキュメントをご覧ください。
https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=AFL_epython#AFL_epython_irisapi_gref

USER>do ##class(%SYS.Python).Shell()
 
Python 3.9.5 (default, Jan 31 2022, 17:55:36) [MSC v.1927 64 bit (AMD64)] on win32
Type quit() or Ctrl-D to exit this shell.
>>> import pandas
>>> glo=iris.gref('^ISJ')
>>> glo.kill([None])
>>> df=pandas.read_excel('c:\\temp\\test.xlsx', header=None)
>>> for key,row in df.iterrows():
...  moji=','.join(list(map(str, row)))
...  glo[key]=moji
...
>>> exit()
 
USER>zw ^ISJ
^ISJ(0)="Name,Age,Address"
^ISJ(1)="佐藤,50,東京"
^ISJ(2)="加藤,40,大阪"
^ISJ(3)="伊藤,30,京都"
 
USER>

 

以下の関連記事も、ぜひご覧ください。

PandasデータフレームをIRISに保存する - 簡易メモ
InterSystems IRIS グローバル($LB) を pandas.DataFrame に変換する

3
0 154
ディスカッション (2)0
続けるにはログインするか新規登録を行ってください

@Megumi Kakechi さん、役に立つ記事ありがとうございます!

細かい点ですが、クラスメソッドから、同じクラスの別のクラスメソッドを呼ぶときに、

iris.cls("User.PythonTest").fromPythonString(moji)

のように呼んでますが、クラス名を繰り返さずに、

iris.cls(__name__).fromPythonString(moji)

で呼べるようです。(参考:英語のコミュティティ記事

Pythonなら、clsという変数で自分のクラスへの参照が入って欲しいのですが、これは将来の改善を待たないといけないみたいです。

@Minoru Horita さん

情報ありがとうございます!
__name__で呼べるとは、スマートでいいですね。
早速記事に反映させていただきました。