

# AWS Glue에서 JSON 형식 사용
<a name="aws-glue-programming-etl-format-json-home"></a>

AWS Glue는 소스에서 데이터를 검색하고 다양한 데이터 형식으로 저장 및 전송되는 대상에 데이터를 씁니다. 데이터가 JSON 데이터 형식으로 저장 또는 전송되는 경우 이 문서에서는 AWS Glue에서 데이터를 사용하는 데 사용할 수 있는 기능을 소개합니다.

AWS Glue는 JSON 형식 사용을 지원합니다. 이 형식은 행이나 열을 기반으로 하지 않는 일관된 모양이지만 유연한 내용의 데이터 구조를 나타냅니다. JSON은 여러 기관에서 발행한 병렬 표준으로 정의되며 그 중 하나는 ECMA-404입니다. 일반적으로 참조되는 소스의 형식에 대한 소개는 [JSON 소개](https://www.json.org/)를 참조하세요.

AWS Glue를 사용하여 Amazon S3에서 JSON 파일과 `bzip` 및 `gzip` 압축된 JSON 파일을 읽을 수 있습니다. 이 페이지에서 설명하는 구성 대신 [S3 연결 파라미터](aws-glue-programming-etl-connect-s3-home.md#aws-glue-programming-etl-connect-s3)에서 압축 동작을 구성할 수 있습니다.


| 읽기 | 쓰기 | 스트리밍 읽기 | 작은 파일 그룹화 | 작업 북마크 | 
| --- | --- | --- | --- | --- | 
| 지원 | 지원 | 지원 | 지원 | 지원 | 

## 예: S3에서 JSON 파일 또는 폴더 읽기
<a name="aws-glue-programming-etl-format-json-read"></a>

** 사전 조건:** 읽으려는 JSON 파일 또는 폴더에 대한 S3 경로(`s3path`)가 필요합니다.

**구성:** 함수 옵션에서 `format="json"`를 지정합니다. `connection_options`에서 `paths` 키를 사용하여 `s3path`를 지정합니다. 연결 옵션에서 읽기 작업이 s3를 통과하는 방법을 추가로 변경할 수 있습니다. 자세한 내용은 [Amazon S3 연결 옵션 참조](aws-glue-programming-etl-connect-s3-home.md#aws-glue-programming-etl-connect-s3)를 참조하세요. 리더에서 `format_options`의 JSON 파일을 해석하는 방법을 구성할 수 있습니다. 자세한 내용은 [JSON 구성 참조](#aws-glue-programming-etl-format-json-reference)를 참조하세요.

 다음 AWS Glue ETL 스크립트는 S3에서 JSON 파일 또는 폴더를 읽는 프로세스를 보여 줍니다.

------
#### [ Python ]

이 예에서는 [create\$1dynamic\$1frame.from\$1options](aws-glue-api-crawler-pyspark-extensions-glue-context.md#aws-glue-api-crawler-pyspark-extensions-glue-context-create_dynamic_frame_from_options) 메서드를 사용합니다.

```
# Example: Read JSON from S3
# For show, we handle a nested JSON file that we can limit with the JsonPath parameter
# For show, we also handle a JSON where a single entry spans multiple lines
# Consider whether optimizePerformance is right for your workflow.

from pyspark.context import SparkContext
from awsglue.context import GlueContext

sc = SparkContext.getOrCreate()
glueContext = GlueContext(sc)
spark = glueContext.spark_session

dynamicFrame = glueContext.create_dynamic_frame.from_options(
    connection_type="s3",
    connection_options={"paths": ["s3://s3path"]},
    format="json",
    format_options={
        "jsonPath": "$.id",
        "multiline": True,
        # "optimizePerformance": True, -> not compatible with jsonPath, multiline
    }
)
```

또한 스크립트(`pyspark.sql.DataFrame`)에서 DataFrame을 사용합니다.

```
dataFrame = spark.read\
    .option("multiline", "true")\
    .json("s3://s3path")
```

------
#### [ Scala ]

이 예에서는 [getSourceWithFormat](glue-etl-scala-apis-glue-gluecontext.md#glue-etl-scala-apis-glue-gluecontext-defs-getSourceWithFormat) 작업을 사용합니다.

```
// Example: Read JSON from S3
// For show, we handle a nested JSON file that we can limit with the JsonPath parameter
// For show, we also handle a JSON where a single entry spans multiple lines
// Consider whether optimizePerformance is right for your workflow.

import com.amazonaws.services.glue.util.JsonOptions
import com.amazonaws.services.glue.{DynamicFrame, GlueContext}
import org.apache.spark.SparkContext

object GlueApp {
  def main(sysArgs: Array[String]): Unit = {
    val spark: SparkContext = new SparkContext()
    val glueContext: GlueContext = new GlueContext(spark)

    val dynamicFrame = glueContext.getSourceWithFormat(
      formatOptions=JsonOptions("""{"jsonPath": "$.id", "multiline": true, "optimizePerformance":false}"""),
      connectionType="s3",
      format="json",
      options=JsonOptions("""{"paths": ["s3://s3path"], "recurse": true}""")
    ).getDynamicFrame()
  }
}
```

또한 스크립트(`pyspark.sql.DataFrame`)에서 DataFrame을 사용합니다.

```
val dataFrame = spark.read
    .option("multiline", "true")
    .json("s3://s3path")
```

------

## 예: S3에 JSON 파일 및 폴더 쓰기
<a name="aws-glue-programming-etl-format-json-write"></a>

** 사전 조건:** 초기화된 DataFrame(`dataFrame`) 또는 DynamicFrame(`dynamicFrame`)이 필요합니다. 예상되는 S3 출력 경로(`s3path`)도 필요합니다.

**구성:** 함수 옵션에서 `format="json"`를 지정합니다. `connection_options`에서 `paths` 키를 사용하여 `s3path`를 지정합니다. `connection_options`에서 라이터가 S3와 상호 작용하는 방식을 추가로 변경할 수 있습니다. 자세한 내용은 AWS Glue: [Amazon S3 연결 옵션 참조](aws-glue-programming-etl-connect-s3-home.md#aws-glue-programming-etl-connect-s3)의 ETL 입력 및 출력에 대한 데이터 형식 옵션을 참조하세요. 작성기에서 `format_options`의 JSON 파일을 해석하는 방법을 구성할 수 있습니다. 자세한 내용은 [JSON 구성 참조](#aws-glue-programming-etl-format-json-reference)를 참조하세요.

다음 AWS Glue ETL 스크립트는 S3에서 JSON 파일 또는 폴더를 쓰는 프로세스를 보여 줍니다.

------
#### [ Python ]

이 예에서는 [write\$1dynamic\$1frame.from\$1options](aws-glue-api-crawler-pyspark-extensions-glue-context.md#aws-glue-api-crawler-pyspark-extensions-glue-context-write_dynamic_frame_from_options) 메서드를 사용합니다.

```
# Example: Write JSON to S3

from pyspark.context import SparkContext
from awsglue.context import GlueContext

sc = SparkContext.getOrCreate()
glueContext = GlueContext(sc)

glueContext.write_dynamic_frame.from_options(
    frame=dynamicFrame,
    connection_type="s3",
    connection_options={"path": "s3://s3path"},
    format="json"
)
```

또한 스크립트(`pyspark.sql.DataFrame`)에서 DataFrame을 사용합니다.

```
df.write.json("s3://s3path/")
```

------
#### [ Scala ]

이 예에서는 [getSinkWithFormat](glue-etl-scala-apis-glue-gluecontext.md#glue-etl-scala-apis-glue-gluecontext-defs-getSinkWithFormat) 메서드를 사용합니다.

```
// Example: Write JSON to S3

import com.amazonaws.services.glue.util.JsonOptions
import com.amazonaws.services.glue.{DynamicFrame, GlueContext}
import org.apache.spark.SparkContext

object GlueApp {
  def main(sysArgs: Array[String]): Unit = {
    val spark: SparkContext = new SparkContext()
    val glueContext: GlueContext = new GlueContext(spark)

    glueContext.getSinkWithFormat(
        connectionType="s3",
        options=JsonOptions("""{"path": "s3://s3path"}"""),
        format="json"
    ).writeDynamicFrame(dynamicFrame)
  }
}
```

또한 스크립트(`pyspark.sql.DataFrame`)에서 DataFrame을 사용합니다.

```
df.write.json("s3://s3path")
```

------

## JSON 구성 참조
<a name="aws-glue-programming-etl-format-json-reference"></a>

`format="json"`으로 다음 `format_options` 값을 사용할 수 있습니다.
+ `jsonPath` - 레코드로 읽을 객체를 식별하는 [JsonPath](https://github.com/json-path/JsonPath) 표현식. 이것은 외부 배열 안에 중첩된 레코드가 파일에 있을 때 특히 유용합니다. 예를 들어, 다음 JsonPath 표현식은 JSON 객체의 `id` 필드를 대상으로 합니다.

  ```
  format="json", format_options={"jsonPath": "$.id"}
  ```
+ `multiline` - 단일 기록이 다양한 라인을 포괄할 수 있는지 여부를 지정하는 부울 값. 필드가 인용된 새로운 라인 문자를 포함할 때 발생합니다. 이 옵션을 `"true"`로 설정해야 기록이 여러 라인을 포괄할 수 있습니다. 기본값은 `"false"`이라서 파싱 동안 더 많은 공격적 파일 쪼개기가 가능합니다.
+ `optimizePerformance` - Apache Arrow 기반 열 포맷 메모리 포맷과 함께 고급 SIMD JSON 리더를 사용할지 여부를 지정하는 부울 값입니다. AWS Glue 3.0에서만 사용 가능합니다. `multiline` 또는 `jsonPath`와 호환되지 않습니다. 이러한 옵션 중 하나를 제공하면 AWS Glue에서 표준 리더로 돌아갑니다.
+ `withSchema` - [XML 스키마를 수동으로 지정](aws-glue-programming-etl-format-xml-home.md#aws-glue-programming-etl-format-xml-withschema)에 설명된 형식으로 테이블 스키마를 지정하는 문자열 값입니다. 비카탈로그 연결에서 읽을 때 `optimizePerformance`에만 사용됩니다.

## Apache Arrow 열 포맷으로 벡터화된 SIMD JSON 리더 사용
<a name="aws-glue-programming-etl-format-simd-json-reader"></a>

AWS Glue 버전 3.0은 JSON 데이터에 대한 벡터화된 리더를 추가합니다. 이 리더는 특정 조건에서 표준 리더에 비해 2배 더 빠른 성능을 발휘합니다. 이 리더에는 사용하기 전에 사용자가 알아야 할 특정 제한 사항이 있습니다(이 섹션에 설명되어 있음).

최적화된 리더를 사용하려면 `format_options` 또는 테이블 속성에서 `"optimizePerformance"`를 True로 설정합니다. 또한 카탈로그에서 읽지 않는 한 `withSchema`를 제공해야 합니다. `withSchema`는 [XML 스키마를 수동으로 지정](aws-glue-programming-etl-format-xml-home.md#aws-glue-programming-etl-format-xml-withschema)에 설명된 대로 입력을 기대합니다.

```
// Read from S3 data source        
glueContext.create_dynamic_frame.from_options(
    connection_type = "s3", 
    connection_options = {"paths": ["s3://s3path"]}, 
    format = "json", 
    format_options={
        "optimizePerformance": True,
        "withSchema": SchemaString
        })    
 
// Read from catalog table
glueContext.create_dynamic_frame.from_catalog(
    database = database, 
    table_name = table, 
    additional_options = {
    // The vectorized reader for JSON can read your schema from a catalog table property.
        "optimizePerformance": True,
        })
```

AWS Glue 라이브러리에서 *SchemaString* 구축에 대한 자세한 내용은 [PySpark 확장 유형](aws-glue-api-crawler-pyspark-extensions-types.md) 섹션을 참조하세요.

**벡터화된 CSV 리더에 대한 제한 사항**  
다음과 같은 제한 사항이 있습니다.
+ 중첩된 객체 또는 배열 값이 있는 JSON 요소는 지원되지 않습니다. 제공 시 AWS Glue는 표준 리더로 돌아갑니다.
+ 카탈로그에서 또는 `withSchema`를 사용하여 스키마를 제공해야 합니다.
+ `multiline` 또는 `jsonPath`와 호환되지 않습니다. 이러한 옵션 중 하나를 제공하면 AWS Glue에서 표준 리더로 돌아갑니다.
+ 입력 스키마와 일치하지 않는 입력 레코드를 제공하면 리더가 실패할 수 있습니다.
+ [오류 레코드](https://docs.aws.amazon.com/glue/latest/dg/glue-etl-scala-apis-glue-dynamicframe-class.html#glue-etl-scala-apis-glue-dynamicframe-class-defs-errorsAsDynamicFrame)는 생성되지 않습니다.
+ 일본어 또는 중국어와 같은 멀티바이트 문자가 포함된 JSON 파일은 지원되지 않습니다.