Athena에서 AWS Config의 파일을 읽을 때 "HIVE_CURSOR_ERROR: Row is not a valid JSON Object - JSONException: Duplicate key"를 해결하려면 어떻게 해야 하나요?

2분 분량
0

Amazon Athena를 사용하여 AWS Config 파일을 쿼리하면 "Error: HIVE_CURSOR_ERROR: Row is not a valid JSON Object - JSONException: Duplicate key" 오류가 표시됩니다.

간략한 설명

이 오류는 일반적으로 다음과 같은 상황에 발생합니다.

  • AWS Config 리소스에 이름이 같은 태그가 여러 개 있습니다.
  • 이 태그 중 몇몇은 대문자이고 몇몇은 소문자입니다.

예를 들어 다음 레코드는 tc:Nametc: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.insensitivefalse로 설정하고, 열 이름을 열 이름과 동일하지 않은 JSON 키로 매핑합니다. 이 문을 실행하기 전에, 다음과 같은 사항에 유의하세요.

  • LOCATION 필드에서 **s3://awsexamplebucket/AWSLogs/**를 Amazon Simple Storage Service(S3) 버킷으로 변경합니다.
  • 모든 매핑(mapping) 속성을 열 이름과 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를 사용하여 Amazon Athena에서 중첩 JSON 및 매핑으로부터 테이블 생성

Amazon Athena에서 JSON 데이터를 읽으려고 하면 오류가 발생합니다.

Hive-JSON-Serde(Github)

AWS 공식
AWS 공식업데이트됨 일 년 전