Amazon Athena を使用して AWS Config ファイルを照会すると、「エラー: HIVE_CURSOR_ERROR: 行は有効な JSON オブジェクトではありません - JSONException: 重複キー。」というエラーが表示されます。
簡単な説明
このエラーは、通常、次の状況で発生します。
- AWS Config リソースに同じ名前のタグが複数ある。
- 一部のタグが大文字で、一部が小文字である。
例えば、次のレコードは tc:Name および tc:name JSON キーを使用します。
{
"fileVersion": "1.0",
"configSnapshotId": "35eced35-a13a-45b7-81e4-446e35616e70",
"configurationItems": [
{
"tags": { "tc:Name": "6", "tc:name": "abc6-38" }
},
{
"tags": { "tc:Name": "6", "tc:name": "abc6-38" }
},
{
"tags": { "tc:Name": "6" }
},
{
"tags": { "tc:name": "6" }
}
]
}
解決方法
次の例のような CREATE TABLE ステートメントを実行します。このステートメントは、Athena テーブルを作成し、case.insensitive を false に設定して、列名と同じではない JSON キーに列名をマッピングします。このステートメントを実行する前に、次の点に注意してください。
- [LOCATION] フィールドで、 s3://awsexamplebucket/AWSLogs/ を Amazon Simple Storage Service (Amazon S3) バケットの名前に置き換えます。
- すべてのマッピングプロパティを列名と JSON キー (例: mapping.fileversion'='fileVersion') に置き換えます。
CREATE EXTERNAL TABLE aws_config_configuration_snapshot (
fileversion STRING,
configsnapshotid STRING,
configurationitems ARRAY < STRUCT <
configurationItemVersion : STRING,
configurationItemCaptureTime : STRING,
configurationStateId : BIGINT,
awsAccountId : STRING,
configurationItemStatus : STRING,
resourceType : STRING,
resourceId : STRING,
resourceName : STRING,
ARN : STRING,
awsRegion : STRING,
availabilityZone : STRING,
configurationStateMd5Hash : STRING,
configuration : STRING,
supplementaryConfiguration : MAP < STRING, STRING >,
tags: MAP < STRING, STRING >,
resourceCreationTime : STRING > >
)
PARTITIONED BY ( dt STRING , region STRING )
ROW FORMAT SERDE
'org.openx.data.jsonserde.JsonSerDe'
WITH SERDEPROPERTIES (
'case.insensitive'='false,
'mapping.fileversion'='fileVersion',
'mapping.configsnapshotid'='configSnapshotId',
'mapping.configurationitems'='configurationItems',
'mapping.configurationitemversion'='configurationItemVersion',
'mapping.configurationitemcapturetime'='configurationItemCaptureTime',
'mapping.configurationstateid'='configurationStateId',
'mapping.awsaccountid'='awsAccountId',
'mapping.configurationitemstatus'='configurationItemStatus',
'mapping.resourcetype'='resourceType',
'mapping.resourceid'='resourceId',
'mapping.resourcename'='resourceName',
'mapping.arn'='ARN',
'mapping.awsregion'='awsRegion',
'mapping.availabilityzone'='availabilityZone',
'mapping.configurationstatemd5hash'='configurationStateMd5Hash',
'mapping.supplementaryconfiguration'='supplementaryConfiguration',
'mapping.configurationstateid'='configurationStateId'
)
LOCATION 's3://awsexamplebucket/AWSLogs/';
パーティションがロードされたテーブルがすでにある場合は、新しい SerDe プロパティをテーブルに追加できます。次のようなステートメントを使用してください。
ALTER TABLE aws_config_configuration_snapshot SET TBLPROPERTIES (
'case.insensitive'='false',
'mapping.fileversion'='fileVersion',
'mapping.configsnapshotid'='configSnapshotId',
'mapping.configurationitems'='configurationItems',
'mapping.configurationitemversion'='configurationItemVersion',
'mapping.configurationitemcapturetime'='configurationItemCaptureTime',
'mapping.configurationstateid'='configurationStateId',
'mapping.awsaccountid'='awsAccountId',
'mapping.configurationitemstatus'='configurationItemStatus',
'mapping.resourcetype'='resourceType',
'mapping.resourceid'='resourceId',
'mapping.resourcename'='resourceName',
'mapping.arn'='ARN',
'mapping.awsregion'='awsRegion',
'mapping.availabilityzone'='availabilityZone',
'mapping.configurationstatemd5hash'='configurationStateMd5Hash',
'mapping.supplementaryconfiguration'='supplementaryConfiguration',
'mapping.configurationstateid'='configurationStateId')
テーブルの準備ができたら、 configurationItem.tags ['TAGNAME'] を使用してタグにアクセスします。例えば、tc:Name タグにアクセスするには、次のクエリを実行します。
SELECT configurationItem.tags['tc:Name']
FROM your_table
CROSS JOIN unnest(configurationItems) AS t(configurationItem)
WHERE configurationItem.tags['tc:Name'] IS NOT NULL
関連情報
JSONSerDe を使用して、ネストされた JSON とマッピングから Amazon Athena でテーブルを作成する
Amazon Athena から JSON データを読み込もうとするとエラーが発生するのは何故ですか
Hive-JSON-Serde (Github)