【AWS Athena】エラー HIVE_BAD_DATA: Field label's type {A} in parquet is incompatible with type {B} defined in table schema でハマった話
私がAWS AthenaおよびAWS Glueでメタデータの取り扱いでハマった話を共有いたします。
ハマった経緯
- parquetのデータをS3に配置する
- Glueのテーブルを作成する
- AthenaでSELECT文を実行するため、load partition()を実行しパーティションを読み込む
- AthenaでSELECT文を実行する → parquet内でのデータ型の定義とGlueテーブルのテーブル定義に齟齬があるためエラーと表示される
- テーブル定義を誤っていたことに気づきGlueのテーブル情報を修正する
- AthenaでSELECT文を実行する → なぜかparquet内でのデータ型の定義とGlueテーブルのテーブル定義に齟齬があるためエラーと表示される(困惑)
ハマった状況を再現
そのとき、ハマった状況を再現していきます。
まず、S3に配置するparquetをpysparkを使って作成する。
from pyspark.sql.types import StructType
from pyspark.sql.types import StructField
from pyspark.sql.types import StringType
from pyspark.sql.types import IntegerType
rdd = sc.parallelize([
('apple', 120),
('banana', 220),
('tomato', 320),
('chicken', 300),
])
schema = StructType([
StructField('label', StringType(), False),
StructField('value', IntegerType(), False),
])
df = spark.createDataFrame(rdd, schema)
df.repartition(1).write.parquet('./output/')
dfの中身はこのようになっております。
labelのカラムがstring型、valueのカラムがint型です。
これをS3に配置します。今回は s3://inu-is-dog/2020-04-19-qiita/id=123/part-00000.snappy.parquet へ配置いたしました。
id=123がパーティションとなるのがミソです。
次にGlueでテーブルを手動で作成いたします。
- データベース名:sampledb
- テーブル名:table_20200419
- データストア:s3://inu-is-dog/2020-04-19-qiita/
- データ形式:Parquet
- スキーマ:
- id(パーティションキー) [string]
- label [int]
- value [int]
あえて、スキーマのlabelのデータ型はstring型ではなく、int型(誤り)としています。
次にAthenaの画面に遷移します。
今回はidのパーティションを持つテーブルを作成したため、SELECT文を実行する前にid=123のパーティションを登録する。
ALTER TABLE sampledb.table_20200419 ADD PARTITION (id = '123');
それでは、SELECT文を実行してみましょう。
SELECT *
FROM sampledb.table_20200419;
"HIVE_BAD_DATA: Field label's type BINARY in parquet is incompatible with type int defined in table schema"とエラーが表示されました。
Glueのテーブル登録でlabelのデータ型を誤って登録していたことが原因でしょう。
...ということで、table_20200419のスキーマの編集を行いました。
これで先ほどのSELECT文は通るはず....
ダメでした.... 同じエラーメッセージです。(困惑)
Athenaの画面の左側のテーブル情報を見てもわかるのですがlabelのカラムは正常にstring型に更新されております。
それなら、なぜまた同じエラーメッセージなのか??
原因
Glueのテーブル table_20200419へ画面を遷移させ、[パーティションの表示] → [id=123のプロパティの表示]をさせてみましょう。
id=123のパーティションではlabelはint型で扱うように設定されていることがわかります。
パーティションごとのメタデータはそのパーティションを読み込んだ際のテーブル情報が登録されており、大元のテーブルの変更は反映されていないということになります。
対処法
この原因を踏まえて、大元のテーブルのカラム情報が変更された際には今まで読み込んでいたパーティションのメタデータも更新する必要があることがわかりました。
パーティションをDROPした後、改めてパーティションを読み込む対応方法を共有いたします。
ALTER TABLE sampledb.table_20200419 DROP PARTITION (id = '123');
ALTER TABLE sampledb.table_20200419 ADD PARTITION (id = '123');
この記事がみなさまの開発や分析の一助となれば幸いです。
Author And Source
この問題について(【AWS Athena】エラー HIVE_BAD_DATA: Field label's type {A} in parquet is incompatible with type {B} defined in table schema でハマった話), 我々は、より多くの情報をここで見つけました https://qiita.com/yoshiyama_hana/items/f2637aabb7ec83bcc8d7著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .