【IRIS/Cache】コマンドによるグローバルのインポート/エクスポート

本記事は、コマンドによるグローバルのインポート/エクスポートについて解説します。

※この記事は下記の方向けになります。
  • エクスポート時データ量が1kbだった時の絶望を知っている方
  • コマンドでグローバルのインポート/エクスポートを行いたい方

はじめに

【事例】

管理ポータル画面からグローバルをエクスポートしようとしました。

そのシステムは、1つのネームスペースに複数のデータベースからグローバルマッピングしていました。
まぁ、ごくごく普通のDB構成ですよね。

そこで、必要なグローバルを探してエクスポートを実行したら・・・出力されたファイルが1KBのサイズで、中身がスッカスカのファイルでした・・・。

って苦い経験した事ありませんか?

例えば、こんな感じでエクスポートを実行したら・・・

中身がスッカスカのファイルサイズ1KBのGOFファイルでした・・・とか。

グローバルのエクスポートが失敗した!

って、忘れた頃に時々やらかしちゃいますよね・・・

正しい操作は、場所を「Database」に変更してエクスポートの実行になります。

すると、ちゃんとエクスポートが実行されます。

やらかす方が圧倒的に悪いのですが、せめてシステムで制限や警告を行って欲しいなとも思います。

とは言え、文句を言っても解決しないので、コマンドからグローバルをエクスポートする方法を使用して問題を解決していきましょう。

エクスポートする

グローバルをエクスポートするには、「$SYSTEM.OBJ.Export()」を利用します。

【サンプルPG】

ClassMethod export(gblNm As %String, dir As %String, qspec As %String = "")
{
	s exNm = $zstrip(gblNm, "<", "^")
	
	s sts = $SYSTEM.OBJ.Export(exNm_".GBL", dir_"\"_exNm_".xml", qspec, .err)
	w:($$$ISERR(sts)) err
}

Exportの第1引数には、「^(キャレット)」を除外し、末尾に「.GBL」を付与します。

では、グローバル「^developer.data.Defrag1D」を「D:\Temp\output」にエクスポートしてみましょう。

s path = “D:\Temp\output”
d ##class(developer.Sample).export(“^developer.data.Defrag1D”, path)

ターミナルで実行すると、下記メッセージが表示されます。

XMLエクスポートの開始 06/21/2025 13:51:01
グローバルをエクスポート中: ^developer.data.Defrag1D
エクスポートが正常に完了しました。

グローバルがエクスポートされました。
これで、1KBファイルの悲劇が回避できそうです!

データ・クラスの関連グローバルをエクスポートする

データ・クラスには「D」「I」「S」のグローバルがあり、グローバル名は「クラス名 + D」とかになっていると思います。

ただ、日本語のクラス名だったり、ハッシュ値にしていたりすると、クラス名からグローバル名が連想できなくなり、エクスポートもグローバル名を調べないと難しいです。

そのため、クラス名から「D」「I」「S」をエクスポートするサンプルPGを作成しましょう。

ClassMethod clsDataExport(clsNm As %String, dir As %String, qspec As %String = "")
{
	s obj=##class(%Dictionary.ClassDefinition).%OpenId(clsNm)	
	s strg = obj.Storages
	s strgDefi = strg.GetAt(1)
	f propNm="DataLocation","IndexLocation","StreamLocation" {
		s gblNm=$Property(strgDefi, propNm)
		continue:('$d(@gblNm))
		
		s exNm = $tr(gblNm, "^", "")
		, fileNm = dir_"\"_clsNm_"-"_$e(gblNm, *)_".xml"
		
		// エクスポート実行
		k err
		s sts = $system.OBJ.Export(exNm_".GBL", fileNm, qspec, .err)
		w:($$$ISERR(sts)) err
	}
}

では、クラス「developer.data.Defrag1」の関連グローバルを「D:\Temp\output」にエクスポートしてみましょう。

s path = “D:\Temp\output”
d ##class(developer.Sample).clsDataExport(“developer.data.Defrag1”, path)

ターミナルで実行すると、下記ファイルが作成されます。

注)レコード数が異なるため、先ほどのエクスポートファイルとファイルサイズが異なります。

これでデータ・クラスのグローバル・エクスポートも楽になります。

インポートする

グローバルをインポートするには、「d $SYSTEM.OBJ.Load()」を利用します。

【サンプルPG】

ClassMethod import(file As %String, qspec As %String = "")
{
	s sts = $system.OBJ.Load(file, qspec, .err)
	w:($$$ISERR(sts)) err
}

では、先ほど出力したファイル「developer.data.Defrag1-D.xml」をインポートしてみましょう。
 ※ インポート前にグローバルの削除を行っています。

s path = “D:\Temp\output”
d ##class(developer.Sample).clsDataExport(“developer.data.Defrag1”, path)

ターミナルで実行すると、下記メッセージが表示されます。

ロード開始 06/21/2025 15:12:00
ファイル D:\Temp\output\developer.data.Defrag1-D.xml を xml としてロード中
インポートしたグローバル: ^developer.data.Defrag1D
ロードが正常に完了しました。

無事、データ・クラスのグローバルが復帰しました。

データ・クラスの関連グローバルをインポートする

データ・クラスにある「D」「I」「S」の3ファイルをインポートするのに、3回もコマンドを実行するのは、正直面倒です。

そこで、クラス名を引数にして、3ファイルをインポートする仕組みを作成してみましょう。

【サンプルPG】

ClassMethod clsDataImport(clsNm As %String, dir As %String, qspec As %String = "")
{
	s stmt = ##class(%SQL.Statement).%New(1)
	d stmt.%PrepareClassQuery("%Library.File", "FileSet")
	s rset = stmt.%Execute(dir)
	while(rset.%Next()) {
		i (rset.%Get("Type") = "F"){
			s path = rset.%Get("Name")
			
			s fileNm = ##class(%File).GetFilename(path)
			d:($p(fileNm, "-", 1) = clsNm) ..import(path, qspec)
		}
	}
}

では、クラス「developer.data.Defrag1」の関連グローバルを、まとめてインポートしましょう!

s path = “D:\Temp\output”
d ##class(developer.Sample).clsDataImport(“developer.data.Defrag1”, path)

ターミナルで実行すると、下記グローバルがインポートされます。

これでデータ・クラスを指定して、関連グローバルのインポートが行えるようになりました。

おわりに

いかがだったでしょうか。

データ・クラスの関連グローバルをエクスポートしたりインポートしたりするのは、非常に面倒で手間です。

ただし、コマンドを使えば、データのリストアを非常に手軽に行うことができます。

単体テスト・連携テストの前後や、リリース前のデータバックアップ等に、このコマンドでグローバルのエクスポート/インポートを実行してみてはいかがでしょうか。

以上、グローバルのエクスポート/インポートをコマンドで実行する方法について解説致しました。
本記事が、皆さまの実務や学びの中で、少しでもお役に立てれば幸いです。