1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【AWS Glue】PySparkでjsonを読み込む際、スキーマ定義を別ファイルで定義しておく方法

Posted at

はじめに

GlueのDynamicFrameを使わない場合、スキーマを定義してデータを読み込みたいときってありますよね。
そんな時、スキーマがめちゃくちゃ長くなると、別ファイルに切り出したくなると思います。
その方法のうちの1つを試したので、共有します。

方法

準備するデータ

実際にロードするjsonのデータsample_data.jsonと、カラム定義ファイルschema.jsonを準備します。
今回は、これらのファイルをS3に格納しています。

sample_data.json
{"Name": {"First name": "Taro", "Last name": "Tanaka"}, "Age": 23}
{"Name": {"First name": "Hanako", "Last name": "Yamada"}, "Age": 18}
{"Name": {"First name": "Ichiro", "Last name": "Sato"}, "Age": 38}
schema.json
{
    "fields": [
        {
            "metadata": {},
            "name": "Name",
            "nullable": true,
            "type": {
                "fields": [
                    {
                        "metadata": {},
                        "name": "First name",
                        "nullable": true,
                        "type": "string"
                    },
                    {
                        "metadata": {},
                        "name": "Last name",
                        "nullable": true,
                        "type": "string"
                    }
                ],
                "type": "struct"
            }
        },
        {
            "metadata": {},
            "name": "Age",
            "nullable": true,
            "type": "integer"
        }
    ],
    "type": "struct"
}

ロード

S3に、以下のようにデータファイルとスキーマ定義ファイルを格納します。

.
└── sample-bucket
     ├── data
     │   └── sample_data.json
     └── schema
         └── schema.json

その状態で、以下のようなコードをGlueで実行します。

import boto3
import json
from pyspark.sql.types import IntegerType, StringType, StructField, StructType

s3 = boto3.resource('s3')

# schema定義ファイルを読み込む
obj = s3.Object('sample-bucket','schema/schema.json')
response = obj.get()    
body = response['Body'].read()
json_dict = json.loads(body)

# jsonデータを読み込む
schema = StructType.fromJson(json_dict)
df_with_schema = spark.read.schema(schema) \
        .json("s3://sample-bucket/data/")

メリット

  • 別ファイルとしてスキーマ定義を記載できるので、めちゃくちゃ長いスキーマ定義でもコードがきれい!
  • スキーマ定義とコードが分離されるので、スキーマ定義の変更があってもpythonファイルを更新しなくてよい!
  • スキーマファイルのパスをジョブパラメータとすることで、ジョブを使いまわせる!

デメリット

  • pythonに直接スキーマ定義を書くよりも、少し冗長な書き方になる。
  • 直接pythonファイルにスキーマが書かれないため、ぱっと見でスキーマ定義が分からない。
  • スキーマ定義を別ファイルとして作成するため、ファイル数が増加しやすい。

おわりに

メリデメ挙げてみましたが、スキーマ定義と実際のコードが分離されて疎になるのは嬉しいケースが多そうですね。
一度jsonとしてロードした後にparquetなどカラムと型が定義されるファイル形式で出力すると、その後のデータ分析がやりやすそうです。

参考

  • 困ったときは公式ドキュメント

  • 検索で最初に見つけたサイト

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?