クリアフィルター
記事
Mihoko Iijima · 2020年8月5日
IRIS サーバ側で JSON の操作を行う方法を解説します(3つのビデオに分かれています)。
ビデオ① :ダイナミックエンティティの操作練習
ビデオ② :ダイナミックエンティティで利用できるメソッドの練習
ビデオ③ :SQL関数と %JSON.Adapter の使い方
なお、このビデオには、以下の関連ビデオがあります。ぜひご参照ください。
IRISの基本操作についてのビデオ(索引ページ)
InterSystems開発者コミュニティ biginnerタグ一覧
ビデオ①
このビデオの目次は以下の通りです。
最初~ 復習ビデオ/関連ビデオについて など
IRIS で 作成する REST サーバの仕組み
手動によるRESTディスパッチクラスの作成
APIファーストによるRESTディスパッチクラスの作成
2:05~ JSONとは?
3:26~ JSONオブジェクト:ダイナミックエンティティの作成
//%DynamicObjectを使用した例
set json=##class(%DynamicObject).%New()
set json.Name="テスト太郎"
set json.Address="東京都新宿区"
write json.%ToJSON()
// 出力結果は以下の通り
{"Name":"テスト太郎","Address":"東京都新宿区"}
//リテラルJSONコンストラクタ {} を使用した例
set json={} // %DynamicObjectと一緒
set json.Name="テスト太郎",json.Address="東京都新宿区"
write json.%ToJSON()
// 出力結果は以下の通り
{"Name":"山田太郎","Address":"東京都新宿区"}
7:25~ JSON配列:ダイナミックエンティティでの作成例
//%DynamicArrayを使用した例
set array=##class(%DynamicArray).%New()
set array."0"="配列1" // 配列はインデックス番号0からスタート
set array."1"="配列2"
write array.%ToJSON()
// 出力結果は以下の通り
["配列1","配列2"]
//リテラルJSONコンストラクタ [] を使用した例
set array=[] // %DynamicArrayと一緒
set array."0"="配列1",array."1"="配列2"
write array.%ToJSON()
// 出力結果は以下の通り
["配列1","配列2"]
9:49~ ダイナミックエンティティ操作用のメソッド
※ ビデオ②に続きます
先頭へ戻る
ビデオ②
もくじは以下の通りです。
00:00~ %Set()、%Get()、%Remove() オブジェクト編
set obj={}
set obj.Name="山田太郎"
do obj.%Set("Zip","160-0023")
do obj.%Set("Tel","03-5321-6200")
write obj.%ToJSON()
write obj.%Get("Zip")," - ",obj.%Get("Name")
do obj.%Remove("Zip")
write obj.%ToJSON()
set obj.Pref="東京都"
write obj.%ToJSON()
do obj.%Set("City","新宿区")
write obj.%ToJSON()
02:02~ %Set()、%Get()、%Remove() 配列編
set array=[]
do array.%Set(0,"最初")
write array.%ToJSON()
set array."4"="最後" //set array."番号"="値" は array.%Set("番号","値")と同等
do array.%Set(2,"真中")
write array.%ToJSON()
do array.%Pop()
write array.%ToJSON()
do array.%Push("Pushしたデータ")
write array.%ToJSON()
do array.%Remove(1) // 左から2番目の null を削除
write array.%ToJSON()
03:34~ JSON配列 要素の操作:%Size()、%Get()
set array=["最初",null,""]
do array.%Set(4,"最後") // インデックス番号3 はJSONのnullを設定
write array.%ToJSON()
// 出力結果は以下の通り
["最初",null,"",null,"最後"]
for i=0:1:array.%Size()-1 w array.%Get(i),!
// 出力結果は以下の通り
最初
最後
05:20~ 値が有効値かどうか確認する %IsDefined()
set array=["最初",null,""]
do array.%Set(4,"最後") // インデックス番号3 はJSONのnullを設定
write array.%ToJSON()
// 出力結果は以下の通り
["最初",null,"",null,"最後"]
for i=0:1:array.%Size()-1 {write array.%Get(i)," - 有効値?",array.%IsDefined(i),!}
// 出力結果は以下の通り
最初 - 有効値?1
- 有効値?1
- 有効値?1
- 有効値?0
最後 - 有効値?1
07:38~ 反復処理:配列の場合:%GetIterator()
set array=["最初",null,""]
do array.%Set(4,"最後") // インデックス番号3 はJSONのnullを設定
write array.%ToJSON()
// 出力結果は以下の通り
["最初",null,"",null,"最後"]
set iter=array.%GetIterator()
while iter.%GetNext(.key,.val) { write key," - value= ",val,! }
// 出力結果は以下の通り
0 - value= 最初
1 - value=
2 - value=
4 - value= 最後
09:55~ 反復処理:オブジェクトの場合:%GetIterator()
set obj={"Name":"山田太郎","Zip":"160-0023","Pref":"東京都","City":"新宿区"}
write obj.%ToJSON()
// 出力結果は以下の通り
{"Name":"山田太郎","Zip":"160-0023","Pref":"東京都","City":"新宿区"} set iter=obj.%GetIterator()
set iter=obj.%GetIterator()
while iter.%GetNext(.key,.val) { write key," - value= ",val,! }
// 出力結果は以下の通り
Name - value= 山田太郎
Zip - value= 160-0023
Pref - value= 東京都
City - value= 新宿区
10:11~ JSON null/true/false (ObjectScriptの中での対応)
set array=[null,true,false,1,0,""]
set array."7"="値あり"
for i=0:1:array.%Size()-1 { write i," - ",array.%Get(i),! }
// 出力結果は以下の通り
0 -
1 - 1
2 - 0
3 - 1
4 - 0
5 -
6 -
7 - 値あり
11:40~ JSONのデータタイプを確認する= %GetTypeOf()メソッド
set array=[null,true,false,1,0,""]
set array."7"="値あり"
for i=0:1:array.%Size()-1 {write i," - ",array.%Get(i)," - ",array.%GetTypeOf(i),! }
// 出力結果は以下の通り
0 - - null
1 - 1 - boolean
2 - 0 - boolean
3 - 1 - number
4 - 0 - number
5 - - string
6 - - unassigned
7 - 値あり - string
12:32~ JSONのデータタイプを指定して値を設定する
set array=[]
do array.%Set(0,"","null") // 第2引数はスクリプト上のnull
do array.%Set(1,1,"number") //数字の1として設定
do array.%Set(2,0,"number") //数字の0として設定
do array.%Set(3,1,"boolean") // booleanの1=trueとして設定
do array.%Push(0,"boolean") // booleanの0=false として設定
for i=0:1:array.%Size()-1 { write i," - ",array.%Get(i)," - ",array.%GetTypeOf(i),! }
// 出力結果は以下の通り
0 - - null
1 - 1 - number
2 - 0 - number
3 - 1 - boolean
4 - 0 - boolean
write array.%ToJSON()
// 出力結果は以下の通り
[null,1,0,true,false]
13:38~ ObjectScriptの変数や表現式を [] や {} で使用する方法
set obj={"日付":($ZDATE($H,16)),"時刻":($ZTIME($PIECE($H,",",2)))}
write obj.%ToJSON()
set mgr=$system.Util.ManagerDirectory()
set array=[($system.Util.InstallDirectory()),(mgr)]
write array.%ToJSON()
※ ビデオ③へつづきます
先頭へ戻る
ビデオ③
もくじは以下の通りです。
00:00~ テーブルデータをJSONオブジェクト、JSON配列で取得する方法 概要
関連ビデオのご紹介
基本操作についてのビデオ(索引ページ)
【はじめての InterSystems IRIS】セルフラーニングビデオ:基本その3:IRIS でクラス定義を作ろう(オブジェクト操作の練習)
(Test.Personの作り方を確認する場合に良いビデオ) 上記ビデオの 13:20~(スタジオでの操作)/18:44~(VS Code での操作) で作成方法を紹介しています。
00:54~ SQL:SELECTでの操作 JSON_OBJECT()関数 説明と実演
管理ポータル→システムエクスプローラ→SQL を開き対象ネームスペースに移動後 クエリ実行タブで以下実行します。
SELECT JSON_OBJECT('Name':Name,'Email':Email) ABSENT ON NULL as json from Test.Person
02:42~ JSON_OBJECT()例(埋込SQLでの実行例)
Class Test.JSONTest
{
ClassMethod GetAllPerson()
{
//埋込SQL
&sql(declare C1 cursor for
select JSON_OBJECT('Name':Name,'Email':Email) as json into :json from Test.Person)
&sql(open C1)
set array=[]
for {
&sql(fetch C1)
if SQLCODE'=0 {
quit
}
set obj={}.%FromJSON(json)
do array.%Push(obj)
}
&sql(close C1)
write array.%ToJSON()
}
}
//実行文
do ##class(Test.JSONTest).GetAllPerson()
07:00~ SQL:SELECTでの操作 JSON_ARRAY()関数
管理ポータル→システムエクスプローラ→SQL を開き対象のネームスペースに移動後 クエリ実行タブで以下実行します。
SELECT JSON_ARRAY(Name,Email ABSENT ON NULL) as array from Test.Person
07:50~ JSON_ARRAY()例(ダイナミックSQL実行例)
ClassMethod GetAllPersonArray()
{
set sql="SELECT JSON_ARRAY(Name,Email ABSENT ON NULL) as array from Test.Person"
set stmt=##class(%SQL.Statement).%New()
set status=stmt.%Prepare(sql)
set rset=stmt.%Execute()
set root=[]
while rset.%Next() {
set array=[].%FromJSON(rset.%Get("array"))
do root.%Push(array)
}
do root.%ToJSON()
}
//実行文
do ##class(Test.JSONTest).GetAllPersonArray()
08:59~ JSONアダプタ(%JSON.Adapter)
set person=##class(Test.Person).%OpenId(1)
set status=person.%JSONExport()
write status
10:08~ オブジェクト→JSON文字列を含むストリーム %JSONExportToStream() 説明と実演
set person=##class(Test.Person).%OpenId(1)
set st=person.%JSONExportToStream(.jstream)
write st
write jstream.Read()
write jstream.Rewind()
set jobj={}.%FromJSON(jstream.Read())
write jobj.Name
write jobj.Email
12:59~ オブジェクト→JSON文字列にマッピング %JSONExportToString()
set person=##class(Test.Person).%OpenId(1)
set st=person.%JSONExportToString(.jstring)
write st
write jstring
set jobj={}.%FromJSON(jstring)
write jobj.Name
write jobj.Email
13:20~ JSON文字列→オブジェクトへのマッピング %JSONImport()
set json={}
set json.Name="ジェイソン", json.Email="json@mail.com"
zwrite json
set p1=##class(Test.Person).%New()
set st=p1.%JSONImport(json)
write st
14:24~ 確認できたこと
先頭へ戻る
記事
Toshihiko Minamoto · 2023年1月16日
開発者の皆さん、こんにちは!
InterSystems IRIS で embedded python を使用する一般的なプロジェクトの出発点として推奨できる、最小限の [embedded python テンプレート](https://openexchange.intersystems.com/package/iris-embedded-python-template) をご紹介しましょう。
特徴:
* Embedded python対応
* Embedded Pythonの3つの開発方法の例
* VSCode開発対応
* Dockerが利用可能
* オンラインデモが可能
* ZPM First開発対応。
以下、その特徴について説明しましょう。
まず、Embedded Pythonについて説明します。この機能は InterSystems IRIS 2021.2 に搭載されており、InterSystems IRIS と python を使用したソリューションを開発することができます。 IRIS 2021.2以降では、InterSystems IRISとの共有メモリ環境でpythonスクリプトを実行でき、python開発者は、コードがデータに近いデータベースを使用する際に、独自のオプションを得ることができます。
### Embedded Pythonによる3つの開発モード
### **ObjectScript から python のライブラリをコールする**
これは、[%SYS.Python](https://docs.intersystems.com/irislatest/csp/documatic/%25CSP.Documatic.cls?&LIBRARY=%25SYS&CLASSNAME=%25SYS.Python)クラスにより、Pythonのライブラリをインポートし、ObjectScirptを介してPythonをコールすることができるようになったからです。 [ドキュメント](https://docs.intersystems.com/irisforhealthlatest/csp/docbook/DocBook.UI.Page.cls?KEY=AEPYTHON#AEPYTHON_callpython_library), [例](https://github.com/intersystems-community/iris-embedded-python-template/blob/be578226b7a0c583df1f7b693b1bdae074efb1bd/src/dc/python/PersistentClass.cls#L17). 以下のコードを参照してください。
ClassMethod Today() As %Status
{
Set sc = $$$OK
Set dt = ##class(%SYS.Python).Import("datetime")
write dt.date.today().isoformat()
Return sc
}
### Python で ObjectScript クラスメソッドを記述する
実際、開発者はメソッドのシグネチャに [Language=python] タグを付けて、pure python でコーディングできるようになった。また、ObjectScriptのクラスやグローバルを参照するためのヘルパーpythonライブラリ "iris"も用意されています。 [ドキュメント](https://docs.intersystems.com/irisforhealthlatest/csp/docbookj/DocBook.UI.Page.cls?KEY=AEPYTHON#AEPYTHON_runpython_method)、[例](https://github.com/intersystems-community/iris-embedded-python-template/blob/224be7f5bf80ea0f588f555c7f9e8c8d10c90c10/src/dc/python/PersistentClass.cls#L17)、以下のサンプルコード
ClassMethod CreateRecordPython(propValue As %VarString, ByRef id As %Integer) [ Language = python ]
{
import iris
obj=iris.cls(__name__)._New()
obj.Test=propValue
sc=obj._Save()
id=obj._Id()
return sc
}
### InterSystems IRISソリューションのpure pythonでのコーディング
これは、開発者がIRISを扱う方法の3番目のオプションです。 ここでは、pythonスクリプトをIRISに接続する必要があり、これはENV変数とCallInサービスの "On "を介して行うことができます(詳細は以下を参照)。一度セットアップされたPythonスクリプトは、IRISとの共有メモリで実行されます。ここで、"iris" ライブラリが非常に役に立ちます。 [ドキュメント](https://docs.intersystems.com/irisforhealthlatest/csp/docbook/DocBook.UI.Page.cls?KEY=AEPYTHON#AEPYTHON_runpython_script), [例](https://github.com/intersystems-community/iris-embedded-python-template/blob/master/python/irisapp.py).
def create_rec(var):
obj=iris.cls('dc.python.PersistentClass')._New()
obj.Test=var
obj._Save()
id=obj._Id()
return id
# テストレコード作成
from datetime import datetime
now=str(datetime.now())
print("dc.python.PersistentClass で新しいレコードを作成する")
print(create_rec(now))
## SQLを実行し、データをプリントする
def run_sql(query):
rs=iris.sql.exec(query)
for idx, row in enumerate(rs):
print(f"[{idx}]: {row}")
query="dc_python.PersistentClass から * を選択する"
print("SQLクエリの実行 "+query)
run_sql(query)
### Dockerが可能
テンプレートリポジトリは、コンテナ内でIRISを実行し、Embedded Pythonの調整に必要なすべてをセットアップします。
環境変数。Embedded PythonはIRISに接続してPythonスクリプトを実行するために、特定の環境変数の設定を必要とします。以下は、それを助ける設定を[dockerfile](https://github.com/intersystems-community/iris-embedded-python-template/blob/be578226b7a0c583df1f7b693b1bdae074efb1bd/Dockerfile#L13-L17)に記述しています:
# init Python env
ENV PYTHON_PATH=/usr/irissys/bin/irispython
ENV SRC_PATH=/irisrun/repo
ENV IRISUSERNAME "SuperUser"
ENV IRISPASSWORD "SYS"
ENV IRISNAMESPACE "USER"
また、Embedded Python は CallIn サービスを "ON" にする必要があり、これは docker build フェーズで [iris.script](https://github.com/intersystems-community/iris-embedded-python-template/blob/224be7f5bf80ea0f588f555c7f9e8c8d10c90c10/iris.script#L7) で行われます。
; Embedded Pythonのcallinを可能
do ##class(Security.Services).Get("%Service_CallIn",.prop)
set prop("Enabled")=1
set prop("AutheEnabled")=48
do ##class(Security.Services).Modify("%Service_CallIn",.prop)
また、あなたのソリューションには、いくつかの Python ライブラリのインストールが必要かもしれません。これは、リポジトリのルートにある [requirements.txt](https://github.com/intersystems-community/iris-embedded-python-template/blob/master/requirements.txt) と[dockerfile](https://github.com/intersystems-community/iris-embedded-python-template/blob/224be7f5bf80ea0f588f555c7f9e8c8d10c90c10/Dockerfile#L22)にある pip3 コールによって提供されます:
pip3 install -r requirements.txt && \
### VSCode開発対応
VSCodeでdockerを使って開発するのはとても便利です。Embedded pythonのVSCodeを使ったIRISソリューションをdockerで開発する場合、[Devcontainer mode](https://code.visualstudio.com/docs/remote/containers)に切り替える必要があります。 .devcontainer フォルダに [devcontainer.json ファイル](https://github.com/intersystems-community/iris-embedded-python-template/blob/master/.devcontainer/devcontainer.json) を導入してください。これは、どのDockerサービスと連携する必要があるかを記述しており(私たちのケースではirisです)。コンテナ内で動作しているIRISが使用するPythonエンジンが提供するVSCode内のPythonスクリプトを実行するのに役立ちます。 devcontainer.json ファイルには、コンテナモードでどの [extensions](https://github.com/intersystems-community/iris-embedded-python-template/blob/224be7f5bf80ea0f588f555c7f9e8c8d10c90c10/.devcontainer/devcontainer.json#L43) を使用する必要があるのかを記述したセクションもあります。
"extensions": [
"ms-python.python",
"ms-python.vscode-pylance",
"intersystems-community.vscode-objectscript",
"intersystems.language-server",
"intersystems-community.servermanager",
"ms-vscode.docker"
],
### ZPMを使用したEmbedded Pythonソリューションのインストール
このテンプレートは、「ZPM first」開発リポジトリとして設定されています。つまり、開発したコードはすべて module.xml に記述され、Docker イメージをビルドするたびに ZPM モジュールとしてインストールされます。つまり、開発者は毎回 iris.script の [次の行](https://github.com/intersystems-community/iris-embedded-python-template/blob/224be7f5bf80ea0f588f555c7f9e8c8d10c90c10/iris.script#L13) からコーディングを開始します:
zpm "load /home/irisowner/irisbuild/ -v":1:1
そして、Embedded pythonのコードもZPMモジュールに記述され、[FILECOPY](https://github.com/intersystems-community/iris-embedded-python-template/blob/224be7f5bf80ea0f588f555c7f9e8c8d10c90c10/module.xml#L11)を介してインストールされます:
この式は、リポジトリ内の /python フォルダにあるすべての python スクリプトをパッケージ化し、ターゲット IRIS インストールの libdir 内の python/ フォルダにインストールしたいことを意味します。python スクリプトが ${libdir}python/ フォルダにコピーされると、ターゲット IRIS マシンの ObjectScirpt または Python からのインポート コールに利用できるようになります。
_**注意:他のPythonコードを誤って上書きしないように、Pythonスクリプトのフォルダ名称は、ユニークなものにしてください。**_
このテンプレートがあなたのお役に立つことを願っています。フィードバック、特にプルリクエストは大歓迎です。