AWS Glue 관계화 변환을 사용하여 데이터를 평탄화하려고 합니다. 피벗된 데이터를 Amazon Simple Storage Service(Amazon S3)에 저장하기 위해 파티션으로 사용할 수 있는 필드는 무엇입니까?
간략한 설명
관계화 변환을 사용하면 관계형 데이터베이스에서 배열 및 구조체와 같은 NoSQL 데이터 구조를 사용할 수 있습니다. Relationalize 변환은 DynamicFrames 모음(Python의 DynamicFrameCollection 및 Scala의 배열)을 반환합니다. Relationalize 변환에 의해 반환되는 모든 DynamicFrame은 Python의 개별 이름과 Scala의 배열 인덱스를 통해 액세스할 수 있습니다.
해결 방법
데이터 Relationalize
이 자습서에서는 다음 스키마를 사용합니다.
|-- family_name: string
|-- name: string
|-- gender: string
|-- image: string
|-- images: array
| |-- element: struct
| | |-- url: string
Python의 경우 다음 Relationalize 구문을 사용합니다.
# AWS Glue Data Catalog: database and table names
db_name = "us-legislators"
tempDir = "s3://awsexamplebucket/temp_dir/"
# Create dynamic frames from the source tables
persons = glueContext.create_dynamic_frame.from_catalog(database=db_name, table_name=tbl_persons)
# Relationalize transformation
dfc = persons.relationalize("root", tempDir)
dfc.select('root_images').printSchema()
dfc.select('root_images').show()
Scala에는 다음과 같은 관계화 구문을 사용합니다.
// AWS Glue Data Catalog: database and table names
val dbName = "us-legislators"
val tblPersons = "persons_json"
// Output Amazon S3 temp directory
val tempDir = "s3://awsexamplebucket/temp_dir"
val persons: DynamicFrame = glueContext.getCatalogSource(database = dbName, tableName = tblPersons).getDynamicFrame()
val personRelationalize = persons.relationalize(rootTableName = "root", stagingPath = tempDir)
personRelationalize(2).printSchema()
personRelationalize(2).show()
피벗된 데이터 해석
이 관계화 변환은 root와 root_images라는 두 개의 스키마를 생성합니다.
root:
|-- family_name: string
|-- name: string
|-- gender: string
|-- image: string
|-- images: long
root_images:
|-- id: long
|-- index: int
|-- images.val.url: string
- id: 배열 요소의 순서(1, 2 또는 3)
- index: 배열의 각 요소에 대한 인덱스 위치
- images.val.url: root_images에서 images.val.url의 값
이러한 필드만 피벗된 데이터를 Amazon S3에 저장하기 위해 파티션 필드로 사용할 수 있습니다. name과 같은 root 테이블 필드는 root_images에 없기 때문에 작동하지 않습니다.
관계화된 데이터를 조인하여 정규화된 데이터 가져오기
root_images의 id 속성은 데이터 집합에서 배열의 순서(1, 2 또는 3)입니다. root의 images 속성은 배열 인덱스의 값을 보유합니다. 즉, images와 id를 사용하여 root와 root_images를 조인해야 합니다. **dynamicFrame.show()**를 실행하여 배열의 순서와 배열 인덱스의 값을 확인할 수 있습니다.
root와 root_images 조인:
Python:
joined_root_root_images = Join.apply(dfc.select('root'), dfc.select('root_images'), 'images', 'id')
Scala:
val joined_root_root_images = personRelationalize(0).join(keys1 = Seq("images"), keys2 = Seq("id"), frame2 = personRelationalize(1))
피벗된 데이터 저장
피벗된 데이터를 파티션을 사용하여 Amazon S3에 저장:
Python:
datasink4 = glueContext.write_dynamic_frame.from_options(frame = dfc.select('root_images'), connection_type = "s3", connection_options = {"path": outputHistoryDir,"partitionKeys":["id"]}, format = "csv",transformation_ctx = "datasink4")
Scala:
참고: 다음 예에서 **personRelationalize(2)**는 root_images로 피벗된 데이터 테이블입니다.
glueContext.getSinkWithFormat(connectionType = "s3",
options = JsonOptions(Map("path" -> paths, "partitionKeys" -> List("id"))),
format = "csv", transformationContext = "").writeDynamicFrame(personRelationalize(2))
피벗된 데이터를 파티션을 사용하지 않고 Amazon S3에 저장:
Python:
datasink5 = glueContext.write_dynamic_frame.from_options(frame = dfc.select('root_images'), connection_type = "s3", connection_options = {"path": outputHistoryDir}, format = "csv",transformation_ctx = "datasink5"
Scala:
참고: 다음 예에서 **personRelationalize(2)**는 root_images로 피벗된 데이터 테이블입니다.
glueContext.getSinkWithFormat(connectionType = "s3",
options = JsonOptions(Map("path" -> paths)),
format = "csv", transformationContext = "").writeDynamicFrame(personRelationalize(2))
Amazon S3에 데이터를 쓴 후, Amazon Athena에서 데이터를 쿼리하거나 DynamicFrame을 사용하여 Amazon Redshift와 같은 관계형 데이터베이스에 데이터를 씁니다.
관련 정보
AWS Glue 관계화 변환으로 중첩 JSON 쿼리 간소화
코드 예제: 데이터 조인 및 관계화