Amazon Athena で JSON データを読み込もうとすると、エラーが発生します。

最終更新日: 2019 年 11 月 18 日

Amazon Athena で JSON データを読み込もうとすると、NULL または間違ったデータエラーが発生します。どのように解決すればよいですか?

解決方法

一般的な問題として以下が考えられます。

正しい JSON SerDe を使用する

Athena は、次の 2 つの JSON SerDes のいずれかを使用して、JSON データを処理します。

どちらの SerDe を使用しているのかわからない場合は、SerDe の両バージョンをお試しください。 OpenX SerDe を使用する場合は、次の例に示すように、不正な形式のレコードを無視して、エラーの原因となっている行を特定できます。ignore.malformed.jsontrue に設定されている場合、不正な形式のレコードは NULL として返されます。

CREATE EXTERNAL TABLE json (
    a string,
    b int
)
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
WITH SERDEPROPERTIES ( 'ignore.malformed.json' = 'true')
LOCATION 's3://awsexamplebucket';

新しいテーブルをクエリして、不正な形式のレコードを持つファイルを特定します。例:

SELECT "$PATH", * FROM your_table where your_column is NULL

レコードごとに 1 行を使用

次の JSON レコードは正しくフォーマットされています。

{ "id" : 50, "name":"John" }
{ "id" : 51, "name":"Jane" }
{ "id" : 53, "name":"Jill" }

次の JSON レコードの形式が正しくありません。

{
  "id" : 50,
  "name":"John"
},
{
  "id" : 51,
  "name":"Jane"
}
{
  "id" : 53,
  "name":"Jill"
}

これらのレコードはその形式も正しくありません。

{ "id" : 50, "name":"John" } { "id" : 51, "name":"Jane" } { "id" : 53, "name":"Jill" }

各列で正しいデータ型を使用する

次の例の 2 行目にある「age」のデータ型が正しくありません。列は「eleven」ではなく「11」とする必要があります。これにより、次のエラーメッセージが表示されます。 HIVE_BAD_DATA: Error parsing field value 'eleven' for field 1: For input string: "eleven"

{"name":"Patrick","age":35,"address":"North Street"}
{"name":"Carlos","age":"eleven","address":"Flowers Street"}
{"name":"Fabiana","age":22,"address":"Main Street"}

圧縮された JSON ファイルに正しい拡張子を使用する

圧縮された JSON ファイルを使用する場合、ファイルは「.json」で終わり、その後に「.gz」などの圧縮形式の拡張子が続く必要があります。たとえば、gzip ファイルの正しい形式の拡張子は、「myfile.json.gz」です。

大文字と小文字を区別しない列を使用するか、case.insensitive プロパティを false に設定する

Athena はデフォルトで大文字と小文字を区別しません。大文字と小文字のみが異なる列名がある場合 (たとえば、「Column」と「column」) 、Athena はエラー ("HIVE_CURSOR_ERROR: Row is not a valid JSON Object - JSONException: Duplicate key") を生成し、データは Athena に表示されません。この問題を回避する最も簡単な方法は、大文字と小文字を区別しない列でデータを生成することです。

OpenX SerDe を使用する場合は、大文字と小文字を区別するキー名を使用できます。これを行うには、case.insensitive SerDe プロパティを false に設定し、大文字キー用のマッピングを追加します。たとえば、次のように大文字と小文字の列を使用するには:

{"Username": "bob1234", "username": "bob" }

次の SerDe プロパティを使用します。

CREATE external TABLE casesensitive_json (user_name String,username String)
ROW FORMAT serde 'org.openx.data.jsonserde.JsonSerDe'
WITH SERDEPROPERTIES ( 'mapping.user_name' = 'Username','case.insensitive'='false')
LOCATION 's3://awsexamplebucket';

この記事はお役に立ちましたか?

改善できることはありますか?


さらにサポートが必要な場合