AWS Glue 爬网程序无法提取 CSV Headers

AWS Glue Crawler Cannot Extract CSV Headers

我的智慧到此为止...

我有 15 个 csv 文件,它们是通过直线查询生成的,例如:

beeline -u CONN_STR --outputformat=dsv -e "SELECT ... " > data.csv

我选择了dsv,因为一些字符串字段包含逗号并且没有被引号引起来,这更加破坏了胶水。此外,根据文档,内置的 csv 分类器可以处理管道(并且在大多数情况下,它可以)。

无论如何,我将这 15 个 csv 文件上传到 s3 存储桶和 运行 我的爬虫。

一切正常。对于其中的 14 个。

Glue 能够为除一个文件之外的每个文件提取 header 行,命名列 col_0col_1 等,并包括 header 行在我的 select 查询中。

任何人都可以深入了解导致此问题的这个文件可能有何不同吗?

如果有帮助,我觉得这个 csv 文件中的某些字段可能在某些时候以 UTF-16 或其他方式编码。当我最初打开它时,有一些奇怪的“?”角色四处漂浮。

我已经 运行 tr -d '[=15=]0' 试图清理它,但这还不够。

同样,任何线索、建议或实验我都可以 运行 会很棒。顺便说一句,如果爬虫能够做所有事情(即:不需要手动更改模式和关闭更新),我会更喜欢。

感谢阅读。

编辑:

感觉跟这个有关系source:

Every column in a potential header parses as a STRING data type.

Except for the last column, every column in a potential header has content that is fewer than 150 characters. To allow for a trailing delimiter, the last column can be empty throughout the file.

Every column in a potential header must meet the AWS Glue regex requirements for a column name.

The header row must be sufficiently different from the data rows. To determine this, one or more of the rows must parse as other than STRING type. If all columns are of type STRING, then the first row of data is not sufficiently different from subsequent rows to be used as the header.

是的,您关于 header 部分是正确的,如果 CSV 文件包含所有字符串数据,那么 header 也将被视为字符串而不是 header。作为解决方法,请尝试将 属性 'skip.header.line.count'='1' 放入 table 属性中。

关于“?”你应该使用十六进制编辑器来查看这些无效字符并将它们从文件中删除。

我遇到了同样的问题,即当所有列都是字符串时 Glue 无法识别 header 行

我发现在末尾添加一个带有整数的新列可以解决问题

id,姓名,extra_column sdf13,狗,1

您提到的最后一个文件可能启用了第一个索引。保存时将其更改为

df.to_csv('./filenam.csv',index=False)

添加 Custom Classifier 解决了我的类似问题。

您可以通过在创建自定义分类器时将 ContainsHeader 设置为 PRESENT 来避免 header 检测(当所有列都是字符串类型时不起作用),然后提供通过 Header 的列名。创建自定义分类器后,您可以将其分配给爬虫。由于这是添加到爬虫中的,您不需要在事后对架构进行更改,也不要冒这些更改在下一个爬虫 运行 中被覆盖的风险。使用 boto3,它看起来像:

import boto3


glue = boto3.client('glue')

glue.create_classifier(CsvClassifier={
    'Name': 'contacts_csv',
    'Delimiter': ',',
    'QuoteSymbol': '"',
    'ContainsHeader': 'PRESENT',
    'Header': ['contact_id', 'person_id', 'type', 'value']
})

glue.create_crawler(Name=GLUE_CRAWLER,
                    Role=role.arn,
                    DatabaseName=GLUE_DATABASE,
                    Targets={'S3Targets': [{'Path': s3_path}]},
                    Classifiers=['contacts_csv'])

如果 csv 是由 pandas 生成的,并且问题是所有列都是字符串,您可以将 index_label='row_number' 添加到 to_csv 调用以使 pandas 创建为您提供额外的列(没有 index_label pandas 仍会打印索引,但不会打印 header,这仍然会使爬虫感到困惑)。

胶水 header 标识符很脆弱。确保列名是有效的 SQL 名称(即没有空格)并且没有空列名(从 excel 导出时经常发生)

这对我有用,

分类器名称: 'your classifier name'

分类器类型'csv'

列分隔符','(根据您的喜好更改)

引号:'"'(应与列分隔符不同)

列标题:

  • 设置为,'No headings'
  • 您的自定义列名称,例如:userid,username,userphone,useremail

Sample Example of Custom Classfier

我同意@Thom Lane 和@code_freak 使用分类器。这比在整个 string-type 列 table.

的末尾添加一个额外的整数列要好

您可以在此处从 AWS 官方文档中阅读有关分类器的更多信息:https://docs.aws.amazon.com/glue/latest/dg/console-classifiers.html

首先,您需要使用列名列表 (headers) 来探索您的数据。然后将名称列表添加到分类器中。之后,当您创建爬虫时,在“添加有关您的爬虫的信息”步骤中查找自定义分类器并将其添加到您的爬虫中。

这是因为所有列值都是字符串。

我刚刚添加了一个名称为 'id' 的列,所有行的值为 1(任何整数都可以)。它对我有用。