分かりにくいAmazon Athenaでのデータ型の変更方法をまとめる
背景
Amazon Athenaにおいて、既存テーブルのカラムのデータ型を変更する場合、単純に変更できないことがあります。
本内容では、Athenaにおけるデータ型の変更方法について説明します。
また、データの形式としてParquetでデータを扱っていることを前提とします。
概要
AthenaではGlueのデータカタログとS3の実データを利用しています。
データ型を変更するためのポイントは以下の通りです。
AthenaでParquet形式のデータを扱う場合、データカタログのデータ型を変更しただけだとエラーになってしまいます。
Parquet形式のデータはデータ内でデータ型を持っていて、実データとデータ型が異なるためにエラーになります。
ちなみに、JSON形式のデータではエラーになりません。JSONでは厳密にデータ型を持っていないからと思われます。
JSON形式の場合、データカタログのデータ型を変更し、パーティションを再作成することでデータ型を変更できます。
データ型の変更方法
手順に沿って、各内容を説明します。
S3上の実データのデータ型を変更する
実データのデータ型を変更します。データ作成には、いくつか方法があると思いますが、今回はAthenaのCTASを使用します。
クエリでCAST関数を使用して、データ型を変更します。
ここでは、cast(request_processing_time as varchar)
で文字列型に変更して、データを作成します。
また、既存のテーブルからデータ型を変更したテーブルをCREATEするようにします。
これ以降で、本手順で作成したデータのみを利用するためです。
CREATE TABLE default.sample_tmp WITH ( format = 'parquet', parquet_compression = 'SNAPPY', external_location = 's3://hi1280-log/sample/123456789012/elasticloadbalancing/ap-northeast-1/', partitioned_by = ARRAY ['year', 'month', 'day'] ) AS SELECT cast(request_processing_time as varchar) as request_processing_time ,year ,month ,day FROM default.sample
明示的にCAST関数でデータ型を指定しない場合、データの内容に応じてデータ型が決まります。
整数のデータしかない状態だと、int型になってしまうため、CASTが必要になります。
GlueデータカタログのAPIを使って、データ型を変更する
AWS CLIを使う場合、ColumnsのTypeを変更することで、データ型を変更します。
また、Locationの指定で、前手順で作成したデータの配置先を指定するように変更します。
$ aws glue update-table --database-name default --table-input file://table.json
table.json
{ "Name": "sample", ... "StorageDescriptor": { "Columns": [ { "Name": "request_processing_time", "Type": "string" }, ... ], "Location": "s3://hi1280-log/sample/123456789012/elasticloadbalancing/ap-northeast-1/", ... }, ... }
桁数を含むデータ型の変更を行う場合には、APIを介してデータ型を変更する必要があります。
マネージドコンソールから変更する場合、decimal(8,1)といったデータ桁数を含めたデータ型の変更はできないようになっています。
(パーティションがある場合)パーティションを再作成する
パーティションのデータ内には、データ型の情報が存在しています。
既存のパーティションは古いデータ型になっており、そのままAthenaで操作すると該当のパーティションのデータを参照する際にデータ型が異なり、エラーとなってしまいます。
そのため、新しいデータ型に合わせて、パーティションを再作成する必要があります。
パーティションを再作成する際の手順としては以下のとおりです。
既存のテーブルを削除します。
$ aws glue delete-table --database-name default --name sample
これはデータカタログを削除するコマンドなので、S3上の実データは存在します。
再度同じテーブルを作成します。これによって、パーティションが存在しない状態のテーブルを用意します。
$ aws glue create-table --database-name default --table-input file://table.json
AthenaのMSCK REPAIR TABLE
クエリで全パーティションを作り直します。
$ aws athena start-query-execution --query-string "MSCK REPAIR TABLE default.sample"
1000くらいのパーティション数であれば、数分で完了します。パーティションの数が多いとかなり時間がかかります。
まとめ
Athenaでのデータ型の変更においては、データカタログとS3上の実データという2つのリソースでデータ型を意識する必要があり、ハマりどころでした。
このあたりを意識できるとスムーズにデータ型の変更ができると思います。