JSON データ読み取りのベストプラクティス
JavaScript Object Notation (JSON) は、データ構造をテキストとしてエンコードするための一般的な方法です。多くのアプリケーションやツールは、JSON エンコード形式のデータを出力します。
Amazon Athena では、外部データからテーブルを作成し、それらに JSON でエンコードされたデータを含めることができます。このようなタイプのソースデータには、Athena を JSON SerDe ライブラリ と共に使用します。
JSON でエンコードされたデータを読み取るために以下のヒントを使用してください。
-
適切な SerDe、ネイティブ JSON SerDe、
org.apache.hive.hcatalog.data.JsonSerDe
、または OpenX SerDe、org.openx.data.jsonserde.JsonSerDe
を選択します。詳細については、「JSON SerDe ライブラリ」を参照してください。 -
各 JSON エンコード方式のレコードが、プリティプリントではなく、個別の行に入力されていることを確認します。
注記
SerDe では、各 JSON ドキュメントが、レコード内のフィールドを区切る行終端文字なしの、1 行のテキストに収まっていることを想定しています。JSON テキストがプリティプリント形式の場合、テーブルを作成した後にクエリを実行しようとすると、以下のようなエラーメッセージが表示される場合があります。「
HIVE_CURSOR_ERROR: Row is not a valid JSON Object
」、または「HIVE_CURSOR_ERROR: JsonParseException: Unexpected end-of-input: expected close marker for OBJECT
」。詳細については、GitHub の OpenX SerDe のドキュメントで「JSON Data Files」(JSON データファイル) を参照してください。 -
JSON でエンコードされたデータを、大文字と小文字が区別されない列内に生成します。
-
例に示すように、誤った形式のレコードを無視するオプションを指定します。
CREATE EXTERNAL TABLE json_table ( column_a string, column_b int ) ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
WITH SERDEPROPERTIES ('ignore.malformed.json' = 'true')
LOCATION 's3://DOC-EXAMPLE-BUCKET/path/'; -
Athena で、未確定のスキーマを持つソースデータのフィールドを JSON でエンコードされた文字列に変換します。
Athena が JSON データに基づくテーブルを作成するとき、Athena は既存の事前定義されたスキーマに基づいてデータを解析します。しかし、データには事前定義されたスキーマがないものもあります。このような場合におけるスキーマ管理を簡素化するには、多くの場合、不確定のスキーマがあるソースデータのフィールドを Athena で JSON 文字列に変換してから、JSON SerDe ライブラリ を使用することが有用です。
たとえば、さまざまなセンサーからのイベントを一般的なフィールドで発行する IoT アプリケーションについて考えます。これらのフィールドの 1 つに、イベントを送信するセンサー独自のカスタムペイロードを保存する必要があるとします。この場合、スキーマがわからないため、情報を JSON エンコード形式の文字列として保存することをお勧めします。これを実行するには、以下の例にあるように、Athena テーブル内のデータを JSON に変換します。JSON でエンコードされたデータを Athena データ型に変換することも可能です。
Athena データ型から JSON への変換
Athena データ型を JSON データに変換するには、CAST
を使用します。
WITH dataset AS ( SELECT CAST('HELLO ATHENA' AS JSON) AS hello_msg, CAST(12345 AS JSON) AS some_int, CAST(MAP(ARRAY['a', 'b'], ARRAY[1,2]) AS JSON) AS some_map ) SELECT * FROM dataset
このクエリは以下を返します。
+-------------------------------------------+
| hello_msg | some_int | some_map |
+-------------------------------------------+
| "HELLO ATHENA" | 12345 | {"a":1,"b":2} |
+-------------------------------------------+
JSON から Athena データ型への変換
JSON データを Athena データ型に変換するには、CAST
を使用します。
注記
以下の例では、文字列を JSON エンコード形式にするために、JSON
キーワードで開始し、文字列を単一引用符で囲んでいます (例: JSON
'12345'
)。
WITH dataset AS ( SELECT CAST(JSON '"HELLO ATHENA"' AS VARCHAR) AS hello_msg, CAST(JSON '12345' AS INTEGER) AS some_int, CAST(JSON '{"a":1,"b":2}' AS MAP(VARCHAR, INTEGER)) AS some_map ) SELECT * FROM dataset
このクエリは以下を返します。
+-------------------------------------+
| hello_msg | some_int | some_map |
+-------------------------------------+
| HELLO ATHENA | 12345 | {a:1,b:2} |
+-------------------------------------+