Amazon Athenaでクエリ実行時に「The column ‘<column>‘ in table ‘<table>‘ is declared as type ‘double’, but partition ‘Optional[year=<year>/month=<month>/day=<date>]’ declared column ‘<column>‘ as type ‘float’.」というエラーが発生する場合の対処

Glue Tableのカラムを更新した時は、既存のデータだけでなくパーティションのカラムにも齟齬が発生していないか注意しましょう。
2022.10.25

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、CX事業本部 IoT事業部の若槻です。

今回は、Amazon Athenaでクエリ実行時にThe column '<column>' in table '<table>' is declared as type 'double', but partition 'Optional[year=<year>/month=<month>/day=<dat>]' declared column '<column>' as type 'float'.というエラーが発生する場合の対処についてです。

事象

事象発生の経緯から順を追って示していきます。

まずデータのデータカタログとなるGlue Tableを作成しました。

CREATE EXTERNAL TABLE IF NOT EXISTS `default`.`device_table` (`amount` float, `deviceid` string)
PARTITIONED BY (
  `year` string,
  `month` string,
  `day` string
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
STORED AS INPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat'
LOCATION 's3://source-bucket-123456789012/data/'
TBLPROPERTIES ('classification' = 'parquet');

そしてそのテーブルに対してINSERT INTOクエリを実行してデータを作成します。この時year=2022/month=10/day=25に対してパーティションが合わせて作成されます。

INSERT INTO default.device_table (amount, deviceid, year, month, day)
VALUES (0, 'd001', '2022', '10', '25')

パーティションが作成されていますね。

SHOW PARTITIONS default.device_table

year=2022/month=10/day=25

そして、ここで実装の都合により、テーブルのamountカラムをfloat型からdouble型に変更する作業を行いました。

ALTER TABLE default.device_table
REPLACE COLUMNS (amount double, deviceid string)

するとその変更以降、INSERT INTOクエリの実行でエラーが発生するようになりました。

INSERT INTO default.device_table (amount, deviceid, year, month, day)
VALUES (0, 'd001', '2022', '10', '25')

HIVE_PARTITION_SCHEMA_MISMATCH: You are trying to write into an existing partition in a table. The table schema has changed since the creation of the partition. Inserting rows into such partition is not supported. The column 'amount' in table 'device_table' is declared as type 'double', but partition 'Optional[year=2022/month=10/day=25]' declared column 'amount' as type 'float'. If a data manifest file was generated at 's3://aws-sam-cli-managed-default-samclisourcebucket-c376z02dmoa7/athena-query-result-primary-wg/Unsaved/2022/10/25/552a85ee-f4f0-40ff-ba24-4ef9a45cd6bb-manifest.csv', you may need to manually clean the data from locations specified in the manifest. Athena will not delete data in your account. This query ran against the "default" database, unless qualified by the query. Please post the error message on our forum or contact customer support with Query Id: 552a85ee-f4f0-40ff-ba24-4ef9a45cd6bb

原因

エラーメッセージの次の部分で原因が示されていました。

The column 'amount' in table 'device_table' is declared as type 'double', but partition 'Optional[year=2022/month=10/day=25]' declared column 'amount' as type 'float'.

パーティションyear=2022/month=10/day=25の定義でamountカラムがfloat型となっているが、テーブル側の定義はdouble型となっているため、齟齬が生じてエラーとなっていたようです。

パーティションyear=2022/month=10/day=25の詳細なプロパティを見ると、確かにamountカラムがfloat型のままとなっていますね。

テーブルのカラムの型を変更した場合に、変更前に作成されていたパーティションの定義はそのままとなるため、そのパーティションを使用した際に発生するエラーでした。

対処

ALTER TABLE table_name ADD PARTITIONクエリで該当のパーティションを上書きします。

ALTER TABLE default.device_table ADD
PARTITION (year = '2022', month = '10', day = '25')

パーティションのプロパティを見ると、amountカラムがdouble型となりました。

同パーティションに対してINSERT INTOクエリを再度実行してみると、正常に実行できるようになりました!

INSERT INTO default.device_table (amount, deviceid, year, month, day)
VALUES (0, 'd001', '2022', '10', '25')

おわりに

Amazon Athenaでクエリ実行時にThe column '<column>' in table '<table>' is declared as type 'double', but partition 'Optional[year=<year>/month=<month>/day=<dat>]' declared column '<column>' as type 'float'.というエラーが発生する場合の対処についてでした。

Glue Tableのカラムの更新を行った時は、作成済みのデータを改めるだけでなく、作成済みのパーティションも削除や上書きをして改めるようにするべきでした。

参考

以上