Glueの使い方的な⑰(DynamoDBをデータソースにする)

# 概要

GlueがデータソースにDynamoDBをサポートしました。試してみます。
手順は、DDBに権限のあるロールを作り、DDBをクロールするクローラーを作ってクローリングしテーブルを作り、GlueジョブでDDBのデータをETLしてS3に出力する

### ジョブ名
se2_job10

### クローラー名
se2_in7
se2_out10

# 全体の流れ

* 前準備
* IAMポリシー作成しロールに追加
* クローラー作成と実行
* ジョブ作成と実行

# 前準備

### ソースデータ(19件)

※データの内容は以下がDynamoDBのse2_ddb1というテーブルにあります

```csv
deviceid,uuid,appid,country,year,month,day,hour
iphone,11111,001,JP,2017,12,14,12
android,11112,001,FR,2017,12,14,14
iphone,11113,009,FR,2017,12,16,21
iphone,11114,007,AUS,2017,12,17,18
other,11115,005,JP,2017,12,29,15
iphone,11116,001,JP,2017,12,15,11
pc,11118,001,FR,2017,12,01,01
pc,11117,009,FR,2017,12,02,18
iphone,11119,007,AUS,2017,11,21,14
other,11110,005,JP,2017,11,29,15
iphone,11121,001,JP,2017,11,11,12
android,11122,001,FR,2017,11,30,20
iphone,11123,009,FR,2017,11,14,14
iphone,11124,007,AUS,2017,12,17,14
iphone,11125,005,JP,2017,11,29,15
iphone,11126,001,JP,2017,12,19,08
android,11127,001,FR,2017,12,19,14
iphone,11128,009,FR,2017,12,09,04
iphone,11129,007,AUS,2017,11,30,14
```

DynamoDBで確認するとこう

![スクリーンショット 0030-07-12 9.16.21.png](https://qiita-image-store.s3.amazonaws.com/0/27932/6069cf69-02d9-c3ff-652c-29d820616d31.png)

# IAMポリシー作成しロールに追加

"se2_glueddbtest"というポリシーを作成

![スクリーンショット 0030-07-12 8.32.24.png](https://qiita-image-store.s3.amazonaws.com/0/27932/36e7b534-e061-7750-74fc-c77fcd6b5e1d.png)


※ 以下参考
https://docs.aws.amazon.com/glue/latest/dg/console-crawlers.html

```
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "dynamodb:DescribeTable",
        "dynamodb:Scan"
      ],
      "Resource": [
        "arn:aws:dynamodb:region:account-id:table/table-name*"
      ]
    }
  ]
}
```

作成したポリシーをIAMロールにアタッチ

![スクリーンショット 0030-07-12 9.21.22.png](https://qiita-image-store.s3.amazonaws.com/0/27932/c30f7ac2-b327-b8e3-214e-135d79e460f3.png)



# クローラーの作成と実行

以下の手順で、DynamoDBをクロールするクローラーを作成します。

Glueの画面からCrawlersをクリックし"Add Crawler"をクリック

![スクリーンショット 0030-07-12 8.27.06.png](https://qiita-image-store.s3.amazonaws.com/0/27932/587bfa08-dbec-3623-a65a-5d20a7f477d4.png)

Crawler nameに"se2_in7"を入力

![スクリーンショット 0030-07-12 8.28.52.png](https://qiita-image-store.s3.amazonaws.com/0/27932/49763a35-7cf3-adde-0f0c-733b8588b92f.png)

Choose a data store に "DynamoDBを選択

![スクリーンショット 0030-07-12 8.29.01.png](https://qiita-image-store.s3.amazonaws.com/0/27932/e426b98a-01e0-02ee-b2b5-692f72b14479.png)

Table name には DynamoDBのテーブル"se2_ddb1"を選択

![スクリーンショット 0030-07-12 8.29.18.png](https://qiita-image-store.s3.amazonaws.com/0/27932/0453f01b-3008-ac9f-0228-6d27b32ecb1e.png)

IAM role を"test-glue"を選択

![スクリーンショット 0030-07-12 9.30.56.png](https://qiita-image-store.s3.amazonaws.com/0/27932/26f3185f-53ee-5fa5-e8e2-4ba63cd15a04.png)

Databaseに"se2"、prefix に "se2_"を入力し、最後に "Finish" をクリック

![スクリーンショット 0030-07-12 8.29.57.png](https://qiita-image-store.s3.amazonaws.com/0/27932/564b8e1f-ded1-0457-882c-e7cd9da9c844.png)

#### クローラーの実行

"se2_in7"にチェックを入れ、"Run Crawler"をクリックしクローラーを実行する

![スクリーンショット 0030-07-12 8.42.31.png](https://qiita-image-store.s3.amazonaws.com/0/27932/2e6043c8-ebfd-2569-6e6b-51e11be199e4.png)

#### テーブルの確認

"se2_se2_ddb1"のテーブルができていることを確認する

![スクリーンショット 0030-07-12 8.44.33.png](https://qiita-image-store.s3.amazonaws.com/0/27932/7c3912f7-9471-6f89-f899-4dc03475199f.png)

Classificationがdynamodb
Locationがarn:aws:dynamodb:ap-northeast-1:xxxxxxxxxxxx:table/se2_ddb1
を確認する
スキーマがDynamoDBのテーブルと同じであることを確認する

![スクリーンショット 0030-07-12 8.48.23.png](https://qiita-image-store.s3.amazonaws.com/0/27932/b772e42e-3fa7-21d3-52cd-cfed62375ee7.png)

# ジョブ作成

Glueの画面からJobをクリックし、"Add job"をクリック

![スクリーンショット 0030-07-12 8.50.18.png](https://qiita-image-store.s3.amazonaws.com/0/27932/3fd09a66-252e-3e03-d9ba-44045edb5f49.png)

Name に "se2_job10" を入力し、IAM role に "test-glueを選択し、"Next"をクリック

![スクリーンショット 0030-07-12 8.53.07.png](https://qiita-image-store.s3.amazonaws.com/0/27932/ab3b5426-3a38-b208-40c5-b2ae417cf48a.png)

Data source に "se2_se2_ddb1"を選択し"Next"をクリック

![スクリーンショット 0030-07-12 8.53.42.png](https://qiita-image-store.s3.amazonaws.com/0/27932/fbec9852-35df-d2f8-dd8f-d07df91cd354.png)

Create Table in your targetにチェックを入れ、Data storeに"S3"、Formatに"Parquet"、Target pathに"s3://test-glue00/se2/out10"を選択

![スクリーンショット 0030-07-12 8.57.47.png](https://qiita-image-store.s3.amazonaws.com/0/27932/816068da-6350-c56f-43b0-871acc135fca.png)

そのまま"Next"

![スクリーンショット 0030-07-12 9.01.08.png](https://qiita-image-store.s3.amazonaws.com/0/27932/daa64dfd-5177-9ee7-2954-c3c7f7500b3a.png)

次の画面で"Save.."をクリックしジョブが作成され、その次の画面で"Run Job"をクリックする

![スクリーンショット 0030-07-12 9.02.34.png](https://qiita-image-store.s3.amazonaws.com/0/27932/5573d1bd-d7a4-4c2c-1e7f-c8ce496307d4.png)

ジョブ実行中画面

![スクリーンショット 0030-07-12 9.03.53.png](https://qiita-image-store.s3.amazonaws.com/0/27932/34031b6f-9c59-70b3-e409-ad60d9275607.png)

```python:se2_job10
import sys
from awsglue.transforms import *
from awsglue.utils import getResolvedOptions
from pyspark.context import SparkContext
from awsglue.context import GlueContext
from awsglue.job import Job

## @params: [JOB_NAME]
args = getResolvedOptions(sys.argv, ['JOB_NAME'])

sc = SparkContext()
glueContext = GlueContext(sc)
spark = glueContext.spark_session
job = Job(glueContext)
job.init(args['JOB_NAME'], args)
## @type: DataSource
## @args: [database = "se2", table_name = "se2_se2_ddb1", transformation_ctx = "datasource0"]
## @return: datasource0
## @inputs: []
datasource0 = glueContext.create_dynamic_frame.from_catalog(database = "se2", table_name = "se2_se2_ddb1", transformation_ctx = "datasource0")
## @type: ApplyMapping
## @args: [mapping = [("country", "string", "country", "string"), ("month", "long", "month", "long"), ("hour", "long", "hour", "long"), ("year", "long", "year", "long"), ("appid", "long", "appid", "long"), ("deviceid", "string", "deviceid", "string"), ("uuid", "long", "uuid", "long"), ("day", "long", "day", "long")], transformation_ctx = "applymapping1"]
## @return: applymapping1
## @inputs: [frame = datasource0]
applymapping1 = ApplyMapping.apply(frame = datasource0, mappings = [("country", "string", "country", "string"), ("month", "long", "month", "long"), ("hour", "long", "hour", "long"), ("year", "long", "year", "long"), ("appid", "long", "appid", "long"), ("deviceid", "string", "deviceid", "string"), ("uuid", "long", "uuid", "long"), ("day", "long", "day", "long")], transformation_ctx = "applymapping1")
## @type: ResolveChoice
## @args: [choice = "make_struct", transformation_ctx = "resolvechoice2"]
## @return: resolvechoice2
## @inputs: [frame = applymapping1]
resolvechoice2 = ResolveChoice.apply(frame = applymapping1, choice = "make_struct", transformation_ctx = "resolvechoice2")
## @type: DropNullFields
## @args: [transformation_ctx = "dropnullfields3"]
## @return: dropnullfields3
## @inputs: [frame = resolvechoice2]
dropnullfields3 = DropNullFields.apply(frame = resolvechoice2, transformation_ctx = "dropnullfields3")
## @type: DataSink
## @args: [connection_type = "s3", connection_options = {"path": "s3://test-glue00/se2/out10"}, format = "parquet", transformation_ctx = "datasink4"]
## @return: datasink4
## @inputs: [frame = dropnullfields3]
datasink4 = glueContext.write_dynamic_frame.from_options(frame = dropnullfields3, connection_type = "s3", connection_options = {"path": "s3://test-glue00/se2/out10"}, format = "parquet", transformation_ctx = "datasink4")
job.commit()
```

#### Athenaから確認

DynamoDBと同じデータがクエリできている

![スクリーンショット 0030-07-12 9.11.24.png](https://qiita-image-store.s3.amazonaws.com/0/27932/957990e7-d7f4-0cc5-855d-b82bf7405b74.png)

件数も19件で合っている

![スクリーンショット 0030-07-12 9.11.51.png](https://qiita-image-store.s3.amazonaws.com/0/27932/c81fb0c6-41db-dcca-333b-0b6aa38981f7.png)

フォーマットもparquet

![スクリーンショット 0030-07-12 9.12.21.png](https://qiita-image-store.s3.amazonaws.com/0/27932/e22cecaa-2573-cb38-dc10-b49bbabcfbb9.png)

## その他

DynamoDBのRCUについて
GlueによるDynamoDBへのReadにも、DynamoDBのRCUを消費します。

* "dynamodb.input.tableName"：（必須）読み取る元のDynamoDBテーブル。
* "dynamodb.throughput.read.percent"：（オプション）使用する予約済み容量ユニット（RCU）のパーセンテージ。 デフォルトは "0.5"に設定されています。 許容可能な値は、 "0.1"から "1.5"までです

https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-connect.html#aws-glue-programming-etl-connect-dynamodb

## こちらも是非

Glueマニュアル
https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-partitions.html

Glueの使い方まとめ
https://qiita.com/pioho07/items/32f76a16cbf49f9f712f