amazon-web-services - 我如何更正 AWS Glue Crawler/Data Catalog 将 CSV 中的所有字段推断为字符串,而这些字段显然不是?
问题描述
我每周将一个大的 CSV 文本文件上传到按上传日期分区的 S3 路径(可能不重要)。这些文件的架构都是一样的,格式都是一样的,命名约定也是一样的。每个文件包含约 100 列和约 1M 行混合文本/数字类型。原始数据如下所示:
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
当我使用一切 default运行 Crawler 时,像这样使用 Athena 进行查询:
select * from tb_csv_data
...雅典娜的结果是:
ID | 日期 | 细绳 | int_values | 双值 |
---|---|---|---|---|
“6F87U” | 2021-03-21 | “文本” | 0 | 1.1483 |
“8DU87” | 2021-03-22 | “更多文字 | 哦是的” | 1 |
“79LO2” | 2021-03-23 | “摩尔 | 给我呻吟 | 文本 |
这个级别的问题似乎在于正确检测(阅读:忽略)逗号作为引号内的分隔符。因此,我有一个 CSV 分类器,它具有以下特性,已附加到 Crawler,我再次运行 Crawler,并附加了分类器,结果表属性如下:
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
具有与上面相同的简单 Athena 查询的结果表似乎是正确的:
ID | 日期 | 细绳 | int_values | 双值 |
---|---|---|---|---|
6F87U | 2021-03-21 | 文字,是的 | 0 | 1.1483 |
8DU87 | 2021-03-22 | 更多文字,哦,是的 | 1 | 2.525 |
79LO2 | 2021-03-23 | Moar,给我 Moar,文本 | 2 | 3.485489 |
数据类型的预期自动推断应该是这样的(让我们简化并假设日期作为字符串是正确的):
列名 | 数据类型 |
---|---|
ID | 细绳 |
日期 | 细绳 |
细绳 | 细绳 |
int_values | bigint(或长) |
双值 | 双倍的 |
...但相反,它们都是字符串!
列名 | 数据类型 |
---|---|
ID | 细绳 |
日期 | 细绳 |
细绳 | 细绳 |
int_values | 细绳 |
双值 | 细绳 |
我需要这些数据可以准确地从 Athena 查询,因为它在哪里,那么如果不进一步处理原始数据,我该怎么办?我想我可以手动调整控制台中的表属性,但是当我需要整个管道自动化时,这真的正确吗?我还想避免为每个字段在查询中转换类型 80 多次,因为这些列中的大多数都是数字的。我能做些什么?
谢谢!
解决方案
限制来自您在查询中使用的 serde。请参阅本文档中的注释部分,其说明如下:
当您将 Athena 与 OpenCSVSerDe 一起使用时,SerDe 会将所有列类型转换为 STRING。接下来,Athena 中的解析器根据它找到的内容将 STRING 中的值解析为实际类型。例如,当它可以识别它们时,它会将值解析为 BOOLEAN、BIGINT、INT 和 DOUBLE 数据类型。如果值是 UNIX 格式的 TIMESTAMP,Athena 会将它们解析为 TIMESTAMP。如果值在 Hive 格式的 TIMESTAMP 中,则 Athena 将它们解析为 INT。DATE 类型值也被解析为 INT。
对于要检测的日期类型,它必须是 UNIX 数字格式,例如1562112000
根据doc。
推荐阅读
- javascript - 用另一个对象值引用对象名称
- google-app-engine - 广告错误:AdError 1009:VAST 响应文档为空
- c# - 无法创建 UWP - Microsoft .NET Core 5.0.0
- bash - 如何绑定向上箭头键以转到下一个唯一命令(macOS 终端)?
- rest - RESTful 端点过长可以吗?
- python - 从函数/类返回后如何使列表为空
- powershell - 删除内置管理员
- hadoop - 基于hive中每种文件格式的场景
- reactjs - Axios 请求在 React-Native 中返回错误
- sql-server - %%physloc%% 可以用作动态查询的行标识符或键吗?