【问题标题】:Athena returns wrong values for timestamp fields in parquet filesAthena 为镶木地板文件中的时间戳字段返回错误值
【发布时间】:2020-11-21 11:36:47
【问题描述】:

我在这里主要复制我在forum.aws 上看到的一个问题,希望stackoverflow 社区的答案/解释比论坛上的讨论更彻底、更有启发性。

这是我对这个问题的体验: 我使用pandas从python中的数据框制作了一个镶木地板文件,并使用pandas.to_datetime将一个字段/列说生日为datetime64[ns]。这部分过程似乎完美无缺,因为我可以使用pandas.read_parquet 读取镶木地板文件并得到我所期望的,即在 datetime 中输入的日期。 但是,当我将所述 parquet 文件加载到 AWS 并在其上放置一个 athena 表时,读取相同的生日列会产生与 parquet 文件中的日期完全不匹配的垃圾日期。例如:

t = pandas.DataFrame([['Haiti',pandas.to_datetime('1804-01-01')]],columns=['Country','Independence'])
t.to_parquet("s3://<mybucket>/tmp/t.parquet")
|Country | Independence|
|--------|-------------|
|Haiti   | 1804-01-01  |
CREATE EXTERNAL TABLE IF NOT EXISTS default.mytable (
  `Country` string,
  `Independence` timestamp 
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
WITH SERDEPROPERTIES (
  'serialization.format' = '1'
) LOCATION 's3://<mybucket>/tmp/'
TBLPROPERTIES ('has_encrypted_data'='false');

SELECT * FROM "default"."mytable" limit 10;
|Country | Independence             |
|--------|--------------------------|
|Haiti   |-164033-12-18 00:00:00.000|

【问题讨论】:

  • 这是 Parquet 值被存储为微秒,但被解释为毫秒,因此返回了错误的值。您应该将此报告给 AWS 支持。此外,由于 Athena 基于 Presto,您也可以提交问题 github.com/prestosql/presto/issues/new
  • @PiotrFindeisen,谢谢。我发布了issue

标签: python amazon-web-services amazon-s3 parquet amazon-athena


【解决方案1】:

您可以通过“coerce_timestamps”强制 to_parquet 以 Athena 能够理解的格式写入:

t = pandas.DataFrame([['Haiti',pandas.to_datetime('1804-01-01')]],columns=['Country','Independence'])
t.to_parquet("s3://<mybucket>/tmp/t.parquet", coerce_timestamps='ms')
|Country | Independence|
|--------|-------------|
|Haiti   | 1804-01-01  |
CREATE EXTERNAL TABLE IF NOT EXISTS default.mytable (
  `Country` string,
  `Independence` timestamp 
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
WITH SERDEPROPERTIES (
  'serialization.format' = '1'
) LOCATION 's3://<mybucket>/tmp/'
TBLPROPERTIES ('has_encrypted_data'='false');

SELECT * FROM "default"."mytable" limit 10;
|Country | Independence          |
|--------|-----------------------|
|Haiti   |1804-01-01 00:00:00.000|

【讨论】:

  • 这不起作用 pandas 1.1.4 + fastparquet 0.4.1:pandas/io/parquet.py 中的错误,函数 write()" TypeError: write() got an unexpected keyword argument 'coerce_timestamps'
  • 我正在使用 pyarrow,让 pandas 能够读/写 parquet
  • 我猜 kwarg coerce_timestamps 是用 bt pyarrow 处理的,但不是 fastparquet。
  • 你能用pyarrow试试这个解决方案吗?
  • 我找到了一个使用 fastparquet 的解决方案。我将 kwarg times=“int96” 传递给 df.to_parquet() 并生成了一个 int96 datetime 格式的 parquet 文件。 Athena 中的日期时间现在对应于我从 pandas 中输入的内容。
猜你喜欢
  • 1970-01-01
  • 2021-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-11
  • 2021-03-19
  • 1970-01-01
  • 2022-09-26
相关资源
最近更新 更多