

# AWS Glue で JSON 形式を使用する
<a name="aws-glue-programming-etl-format-json-home"></a>

AWS Glue はソースからデータを取得し、さまざまなデータ形式で保存および転送されたターゲットにデータを書き込みます。このドキュメントでは、JSON データ形式で保存または転送されているデータを、AWS Glue で使用するために用意されている機能について説明します。

AWS Glue は、JSON 形式の使用をサポートしています。この形式は、行ベースまたは列ベースではなく、形状は一貫しているが内容は柔軟なデータ構造を表します。JSON は、複数の機関が発行する並列した規格で定義されており、そのうちの 1 つが ECMA-404 です。一般的に参照されるソースによる形式の概要については、「[Introducing JSON](https://www.json.org/)」(JSON の概要) を参照してください。

AWS Glue を使用して、JSON ファイルや `bzip` および `gzip` などの圧縮された JSON ファイルを Amazon S3 から 読み取ることができます。このページで説明する設定ではなく、[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)」を参照してください。リーダーが JSON ファイルを解釈する方法は、`format_options` で設定できます。詳細については、[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")
```

------

## 例: JSON ファイルおよびフォルダを S3 に書き込む
<a name="aws-glue-programming-etl-format-json-write"></a>

**前提条件:** 初期化された DataFrame (`dataFrame`) または DynamicFrame (`dynamicFrame`) が必要です。また、予想される S3 出力パスである `s3path` も必要になります。

**設定:** 関数オプションで `format="json"` を指定します。`connection_options` で、`paths` キーを使用して `s3path` を指定します。ライターが S3 と対話する方法を、`connection_options` でさらに詳しく変更することができます。詳細については、AWS Glue: [Amazon S3 接続のオプションのリファレンス](aws-glue-programming-etl-connect-s3-home.md#aws-glue-programming-etl-connect-s3) の「ETL の入力および出力のデータ形式オプション」を参照してください。ライターが JSON ファイルを解釈する方法は、`format_options` で設定できます。詳細については、[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` – 高度な SIMD JSON リーダーで、Apache Arrow ベースの列指向メモリ形式を使用するかどうかを指定するブール値。これは、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 ファイルはサポートされていません。