DynamoDB出力のJSONをjqで加工する

AWS,bash,DynamoDB

DynamoDBのCLI出力を加工する

DynamoDBのCLI出力結果はJSONフォーマット

  • 以前、下記の記事でも紹介しましたが、「DynamoDBテーブルを特定の条件で抽出したい」という作業があります。しかし、AWSコンソールからテーブルを出力する場合はCSVフォーマットになりますが、CLIの場合はJSONフォーマットとなります。
    ※AWSコンソールの場合、多くのレコードを持つテーブルでのレコード検索ができず、選択肢はCLI のみとなります。
  • JSONフォーマットの扱いに不慣れの場合、下記の記事でも紹介した方法を利用し、CSVフォーマットに変換して、Excelでデータを利用することも1つの方法です。

JSONフォーマットをjqで加工する(1列の抽出)

  • 今回紹介する方法は、jqのツールを使ったJSONの加工方法です。
  • 下記のサンプルは、aws dynamodb scanコマンドで出力されたDynamoDBテーブル出力結果です。JSONフォーマットかつ出力結果に、"N"や"S" などが付いていて少々複雑に思えます。
  • このテーブル出力結果の"N"や"S" は、DynamoDBテーブルのデータ型であり、"N"は数値型、"S"は文字型を表します。他に"BOOL"はブール型、"B"はバイナリ型で表されます。
    • 日付型も"S “(文字列型)で表され、Date の値は、ISO-8601 形式の文字列として格納されます。

{
    "Items": [
        {
            "employeeId": {
                "S": "A12345"
            },
            "timestamp": {
                "S": "20190801064727"
            },
            "officeId": {
                "S": "XY01"
            },
            "TTL": {
                "N": "1572418047"
            }
        },
  • 先ずはaws dynamodbコマンドを使ってテーブルからレコードを抽出し、結果をファイルにリダイレクトします。

$ aws dynamodb scan --table-name dyn-table02 --filter-expression '#a >= :1 and #b < :2' --expression-attribute-values '{ ":1": { "S": "20190801" }, ":2": { "S": "20190802" } }' --expression-attribute-names '{"#a": "timestamp", "#b": "timestamp"}' > 20190801_ID.out
  • 次にjqを使って特定のレコードのみ抽出を試みますが、エラーとなり失敗します。試行錯誤しましたが、結果変わらず。

$ cat 20190801_ID.out | jq -r '.Items[].employeeId.S'
jq: error: ID/0 is not defined at , line 1:
.Items[].employeeId.S
jq: 1 compile error
  • 冷静にエラーメッセージを観察し、DynamoDBテーブルの出力結果に含まれるダブルクォーテーションが不足しているために起きていることが分かりました(環境によっては、ダブルクォーテーションにエスケープが必要かもしれません)。
  • この方法によって、無事に jqを使って特定のレコードのみ抽出に成功しました。

$ cat 20190801_ID.out | jq -r '.Items[]."employeeId"."S"'
  • 最後は、Linuxコマンドのsort, uniq を被せ、加工します。
  • みなさんもJSONフォーマットだからと諦めず、Tryしてみましょう。

$ cat 20190801_ID.out | jq -r '.Items[]."employeeId"."S"' | sort | uniq

JSONフォーマットをjqで加工する(2列以上の抽出)

  • 前述の方法は、jqのツールを使ってJSONから1列のデータを抽出することを利用した加工方法でした。
  • 下記は、JSONから2列のデータを抽出する方法とその応用です。

cat 20190801_ID.out | jq -r '.Items[]|[."employeeId"."S",."officeId"."S"]'
  • しかし、上記方法は出力結果がJSONの構造上複数行に分かれるため、1レコードに連結します。
  • 
    cat 20190801_ID.out | jq -r '.Items[]|[."employeeId"."S",."officeId"."S"]|add'
    

    最後に

    • JSONフォーマットの構造や利用用途に合わせて加工の仕方が変わるため、今回ご紹介した手順はあくまでも参考になります。
    • 私もJSONやjqは使い始めたばかりですので、今後も活用事例をアップしていきます。
     

    AWS,bash,DynamoDB

    Posted by takaaki