クラウド製品を利用しており、そのデータベース機能の定義ファイルをjson形式で生成する必要があり、地域 x テーブル種類数分の数百種類のjsonファイル生成を行ったメモ。
- 地域とテーブルの一覧をjsonで作成
- 一覧ファイルをPowerShellで読み込む
- 最低限必要な整形処理を施し出力
結合が行えない等の制約があるデータベースなため、奇妙なテーブル構成なことはスルー。
元となるjsonファイル
data.json
{
"prefectures": [
{
"code": "Tokyo",
"Name": "東京"
},
{
"code": "Osaka",
"Name": "大阪"
},
{
"code": "Aichi",
"Name": "愛知"
},
{
"code": "Fukuoka",
"Name": "福岡"
}
],
"tables": [
{
"code": "meeting_room",
"name": "会議室",
"field1": "id",
"field2": "floar",
"field3": "capacities"
},
{
"code": "parking",
"name": "駐車場",
"field1": "id",
"field2": "area",
"field3": "space_number",
"field4": "user_name",
"field5": "car_number",
"field6": "expire"
}
]
}
以上のjsonファイルを元に生成したいjsonファイルは、
- Tokyo_metting_room.json
- Tokyo_parking.json
- Osaka_meeting_room.json
- Osaka_parking.json
- ...
複数行のjsonファイルを読み込む
jsonファイルはGet-Content -Path "filename.json"で読み込みが可能ですが、複数行にまたがるjsonファイルを読み込むには、引数に -Raw を追加する。
Get-Content -Path "filename.json" -Raw | ConvertFrom-Json
もし、-Rawをつけずに複数行のjsonファイルを読み込むと、エラーが表示される
Get-Content -Path "filename.json" | ConvertFrom-Json
ConvertFrom-Json : ':' または '}' ではなく無効なオブジェクトが渡されました。
読み込んだjsonファイルのカラムを取得
Get-Contentで読み込んだファイルはObject型、それをパイプでつなぎ、ConvertFrom-JsonでjsonファイルをPSCustomObject型に変換しています。
PSObjectのプロパティにアクセスすることで、Name値が取得できます。
# $objectはPSCustomObjectに変換された、jsonデータ
$object.psobject.Properties | ForEach-Object {
return $_.Name
}
完成系
これらを組み合わた、最終的なソースコード
parse.ps1
<#
Jsonデータから地域 x テーブル種類分のjsonを出力
#>
$file = "data.json" # 読み込む定義ファイル
$export = ".\results" # 出力ディレクトリ
# ファイルの存在確認
if (!(Test-Path -Path $file)) {
exit
}
# 出力フォルダがなければ生成しておく
if (!(Test-Path -Path $export)) {
New-Item -Path $export -ItemType Directory
}
# 定義ファイルを読み込む
# Get-Contentの引数に -Raw を入れることで複数行のjsonファイルを読み込む
Get-Content -Path $file -Encoding UTF8 -Raw | ConvertFrom-Json | ForEach-Object {
$prefectures = $_.prefectures
$tables = $_.tables
# 地域数分ループする
$prefectures | ForEach-Object {
$pref_code = $_.code
$pref_name = $_.name
# $tables数分ループする
$tables | ForEach-Object {
$fields = $_
# カラムの取得
$columns = $fields.psobject.Properties | ForEach-Object {
return $_.Name
}
$json = New-Object PSObject | Select-Object -Property $columns
$table_name = $pref_code + "_" + $fields.code
# カラムの数分ループする
$columns | ForEach-Object {
if ($_ -eq "code") {
$json.code = $pref_code + "_" + $fields.($_)
} elseif ($_ -eq "name") {
$json.name = $pref_name + "_" + $fields.($_)
} else {
$json.($_) = $fields.($_)
}
}
# ファイル出力
$export_directory = "${export}\${table_name}.json"
$json | ConvertTo-Json | Out-File -FilePath $export_directory -Encoding utf8 -Force
}
}
}