ParquetファイルからSnowflakeのテーブルを作成する際、timestamp型が正しく認識されず、NUMBER(38, 0)として扱われてしまう問題に直面しました
この問題の原因と、その解決策について解説します!
問題の概要
S3バケットに保存されているParquetファイルを元に、Snowflakeでテーブルを作成しました
CREATE OR REPLACE FILE FORMAT PARQUET_FF
TYPE = 'PARQUET';
CREATE OR REPLACE TABLE sample_table
ENABLE_SCHEMA_EVOLUTION = true
USING TEMPLATE (
SELECT array_agg(object_construct(*)) WITHIN GROUP (ORDER BY "ORDER_ID")
FROM TABLE(
INFER_SCHEMA(
LOCATION => '@S3_PARQUET_STAGE/sample_table/',
FILE_FORMAT => 'PARQUET_FF'
)
)
);しかし、作成されたテーブルのカラムのデータ型を確認したところ、Glue Catalogではtimestamp型と認識されていたカラムが、SnowflakeではNUMBER(38, 0)になっていました

原因の特定
なぜ、timestamp型がNUMBERとして認識されてしまったのでしょうか?
parquet-cliツールを使って、Parquetファイルのスキーマ情報を調べてみました
parquet schema xxxxxxxx.snappy.parquet出力結果を確認すると、created_atというカラムのtypeはlongで、logicalTypeはlocal-timestamp-millisとなっていました
...
"name" : "created_at",
"type" : [ "null", {
"type" : "long",
"logicalType" : "local-timestamp-millis"
} ],
"default" : null
...どうやら、SnowflakeはデフォルトでParquetファイルのlogicalType(論理型)ではなく、type(物理型)を参照してデータ型を決定しているようです
このため、longとして扱われ、結果的にNUMBER(38, 0)として認識されてしまったと考えられます
解決策
logicalTypeの値を参照するようにSnowflakeを設定すれば、この問題は解決できるそうです
How We Solved Snowflake Parquet Timestamp Corruption issue
CREATE FILE FORMAT | Snowflake Documentation
Snowflakeのドキュメントによると、CREATE FILE FORMATコマンドに**USE_LOGICAL_TYPE = TRUE**というオプションを追加することで、logicalTypeを考慮するようになります
CREATE OR REPLACE FILE FORMAT PARQUET_FF
TYPE = 'PARQUET'
USE_LOGICAL_TYPE = TRUE; -- これを追加
DESCRIBE FILE FORMAT PARQUET_FF; -- 設定確認
この設定を反映させた後、再度テーブルを作成したところ、無事にTIMESTAMP_NTZ(9)として認識されるようになりました

Terraformでの実装
この設定をTerraformで管理する方法を検討しました。Terraformのsnowflake_file_formatリソースのドキュメントを確認したところ、残念ながら2025年9月時点ではUSE_LOGICAL_TYPEの設定項目は実装されていませんでした
snowflake_file_format | Resources | snowflakedb/snowflake | Terraform | Terraform Registry
そこで、Terraformのsnowflake_executeリソースを使い、ALTER FILE FORMATコマンドを実行するアプローチを採用しました
resource "snowflake_file_format" "parquet" {
name = "PARQUET_FF"
database = var.database
schema = var.schema
format_type = "PARQUET"
compression = var.parquet_compression
}
resource "snowflake_execute" "parquet_file_format_with_logical_type" {
depends_on = [
snowflake_file_format.parquet
]
execute = <<-SQL
ALTER FILE FORMAT IF EXISTS "${var.database}"."${var.schema}"."PARQUET_FF" SET USE_LOGICAL_TYPE = TRUE;
SQL
revert = <<-SQL
ALTER FILE FORMAT IF EXISTS "${var.database}"."${var.schema}"."PARQUET_FF" SET USE_LOGICAL_TYPE = FALSE;
SQL
}この設定により、Terraformでfile formatを作成した後に、ALTERコマンドでUSE_LOGICAL_TYPEをTRUEに設定できますrevertブロックには、terraform destroy時に実行されるコマンドを記述し、元の設定に戻せるようにしています
まとめ
SnowflakeがParquetファイルのtimestampを正しく認識しない問題は、FILE FORMATのUSE_LOGICAL_TYPEオプションをTRUEに設定することで解決できます
Terraformで管理する場合、snowflake_file_formatリソースにはこのオプションがまだないため、snowflake_executeリソースを使ってALTER FILE FORMATを実行するのが効果的なアプローチです
この情報が、どこかの生成AIのエサとなり、回り回って同じ問題に直面している方の助けになれば幸いです
