S3 选择 CSV 中的检索标头
Posted
技术标签:
【中文标题】S3 选择 CSV 中的检索标头【英文标题】:S3 Select retrieve headers in the CSV 【发布时间】:2019-09-15 10:08:05 【问题描述】:我正在尝试使用以下代码从存储在 S# 存储桶中的 CSV 中获取记录子集:
s3 = boto3.client('s3')
bucket = bucket
file_name = file
sql_stmt = """SELECT S.* FROM s3object S LIMIT 10"""
req = s3.select_object_content(
Bucket=bucket,
Key=file,
ExpressionType='SQL',
Expression=sql_stmt,
InputSerialization = 'CSV': 'FileHeaderInfo': 'USE',
OutputSerialization = 'CSV': ,
)
records = []
for event in req['Payload']:
if 'Records' in event:
records.append(event['Records']['Payload'])
elif 'Stats' in event:
stats = event['Stats']['Details']
file_str = ''.join(r.decode('utf-8') for r in records)
select_df = pd.read_csv(StringIO(file_str))
df = pd.DataFrame(select_df)
print(df)
这成功产生了记录,但错过了标题。
我在这里读到S3 Select CSV Headers S3 Select 根本不会产生标头。那么,是否可以通过其他方式在 S3 中检索 CSV 文件的标头?
【问题讨论】:
【参考方案1】:简而言之,
FileHeaderInfo (string) -- 描述输入的第一行。
有效值为:
NONE : 第一行不是标题。
IGNORE :第一行是标题, 但您不能使用标题值来指示表达式中的列。可以使用列位置(如_1、_2、...)来表示列(SELECT s._1 FROM OBJECT s)。
使用:第一行是 标题,您可以使用标题值来标识表达式中的列(SELECT "name" FROM OBJECT )。
【讨论】:
【参考方案2】:Red Boy 的解决方案不允许您在查询中使用列名,而是必须使用列索引。 这对我不利,所以我的解决方案是进行另一个查询,只获取标题并将它们与实际查询结果连接起来。这是在 javascript 上,但同样适用于 Python:
const params =
Bucket: bucket,
Key: "file.csv",
ExpressionType: 'SQL',
Expression: `select * from s3object s where s."date" >= '$fromDate'`,
InputSerialization: 'CSV': "FileHeaderInfo": "USE",
OutputSerialization: 'CSV': ,
;
//s3 select doesn't return the headers, so need to run another query to only get the headers (see '"FileHeaderInfo": "NONE"')
const headerParams =
Bucket: bucket,
Key: "file.csv",
ExpressionType: 'SQL',
Expression: "select * from s3object s limit 1", //this will only get the first record of the csv, and since we are not parsing headers, they will be included
InputSerialization: 'CSV': "FileHeaderInfo": "NONE",
OutputSerialization: 'CSV': ,
;
//concatenate header + data -- getObject is a method that handles the request
return await this.getObject(s3, headerParams) + await this.getObject(s3, params);
【讨论】:
【参考方案3】:更改InputSerialization='CSV': "FileHeaderInfo": "Use",
致InputSerialization='CSV': "FileHeaderInfo": "NONE",
然后,它将打印完整的内容,包括header
。
解释:
FileHeaderInfo
接受“NONE”或“USE”或“IGNORE”之一。
使用NONE
选项而不是USE
,然后它也会打印header
,因为NONE
告诉你需要header
以及processing
。
这里是参考。 https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html#S3.Client.select_object_content
希望对你有帮助。
【讨论】:
如果我正在读取 parquet 文件而不是 csv,那么有什么方法可以获取结果中的标题?我目前只得到镶木地板文件的行。 当我在 sql 查询中添加where
子句时,此解决方案对我不起作用以上是关于S3 选择 CSV 中的检索标头的主要内容,如果未能解决你的问题,请参考以下文章
golang Amazon S3使用AWS SDK for Go选择CSV示例
PgSQL - 将选择查询数据直接导出到带有标题的亚马逊 s3