我如何更正 AWS Glue Crawler/Data 目录将 CSV 中的所有字段明显不是字符串的推断?

How can I correct AWS Glue Crawler/Data Catalog inferring all fields in CSV as strings when they're clearly not?

我有一个很大的 CSV 文本文件,每周上传到按上传日期分区的 S3 路径(可能不重要)。这些文件的架构完全相同,格式完全相同,命名约定也完全相同。每个文件包含约 100 列和约 1M 行的混合 text/numeric 类型。原始数据如下所示:

id,date,string,int_values,double_values
"6F87U",2021-03-21,"Text",0,1.1483
"8DU87",2021-03-22,"More text, oh yes",1,2.525
"79LO2",2021-03-23,"Moar, give me moar, text",2,3.485489

当我 运行 具有 一切默认值 的爬虫时,像这样使用 Athena 查询:

select * from tb_csv_data

...Athena 中的结果是:

id date string int_values double_values
"6F87U" 2021-03-21 "Text" 0 1.1483
"8DU87" 2021-03-22 "More text oh yes" 1
"79LO2" 2021-03-23 "Moar give me moar text

这个级别的问题似乎与正确检测(阅读:忽略)逗号作为引号内的分隔符有关。因此,我有一个 CSV 分类器,它具有以下附加到爬虫的特征,我再次 运行 爬虫并附加了分类器,因此得到的 table 属性是:

Input format    org.apache.hadoop.mapred.TextInputFormat
Output format   org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
Serde serialization lib org.apache.hadoop.hive.serde2.OpenCSVSerde

Serde parameters    
quoteChar " 
separatorChar ,

Table properties    
sizeKey 4356512114 
objectCount 3 
UPDATED_BY_CRAWLER crawler-name 
CrawlerSchemaSerializerVersion 1.0 
recordCount 3145398 
averageRecordSize 1384 
CrawlerSchemaDeserializerVersion 1.0 
compressionType none 
columnsOrdered true 
areColumnsQuoted true
delimiter , 
typeOfData file

结果 table 使用与上面相同的简单 Athena 查询似乎是正确的:

id date string int_values double_values
6F87U 2021-03-21 Text, yes 0 1.1483
8DU87 2021-03-22 More text, oh yes 1 2.525
79LO2 2021-03-23 Moar, give me moar, text 2 3.485489

数据类型的预期自动推断应该是这样的(让我们简化并假设日期是正确的字符串):

Column name Data type
id string
date string
string string
int_values bigint (or long)
double_values double

...但它们都是字符串!

Column name Data type
id string
date string
string string
int_values string
double_values string

我需要这些数据可以从 Athena 准确查询,因为它在哪里,那么如果不进一步处理原始数据我能做什么?我想我可以在控制台中手动调整 table 属性,但是当我需要整个管道自动化时,这真的正确吗?我还想避免在查询中为每个字段强制类型转换 80 多次,因为这些列中的大多数都是数字。我能做什么?

谢谢!

限制来自您在查询中使用的 serde。请参阅 this 文档中的注释部分,其中有以下解释:

当您将 Athena 与 OpenCSVSerDe 一起使用时,SerDe 会将所有列类型转换为 STRING。接下来,Athena 中的解析器根据它找到的内容将 STRING 中的值解析为实际类型。例如,当它可以识别值时,它会将值解析为 BOOLEAN、BIGINT、INT 和 DOUBLE 数据类型。如果值采用 UNIX 格式的 TIMESTAMP,Athena 会将它们解析为 TIMESTAMP。如果值采用 Hive 格式的 TIMESTAMP,Athena 会将它们解析为 INT。 DATE 类型值也被解析为 INT.

要检测日期类型,它必须是 UNIX 数字格式,例如 1562112000 根据 doc