我很难让
SelectObjectContent
返回任何详细信息。令人沮丧的是查询在控制台中运行。
我的测试对象是一个存储在测试存储桶中的简单 JSON 文件:
{
"Name": "Kevin",
"Role": "engineer",
"Color": "blue"
}
我的查询也同样简单:
SELECT * FROM s3object LIMIT 5
下面是我为特定用例组装的函数:
func S3SelectObjectContent(bucket, region, objectKey, expression string) (*s3.SelectObjectContentOutput, error) {
client := s3.NewFromConfig(Config, func(o *s3.Options) {
o.Region = region
})
input := &s3.SelectObjectContentInput{
Bucket: &bucket,
Key: &objectKey,
Expression: &expression,
ExpressionType: types.ExpressionTypeSql,
InputSerialization: &types.InputSerialization{
JSON: &types.JSONInput{
Type: types.JSONTypeDocument,
// Type: types.JSONTypeLines
},
CompressionType: types.CompressionTypeGzip,
},
OutputSerialization: &types.OutputSerialization{
JSON: &types.JSONOutput{
RecordDelimiter: aws.String("\n"),
},
},
}
result, err := client.SelectObjectContent(context.TODO(), input)
if err != nil {
return nil, err
}
return result, nil
}
预先感谢您的帮助和想法。
我尝试调整
bucket
和 objectKey
...如果这些不正确,我会得到“未找到”。
我已确认我可以访问该存储桶,因为我可以使用
ListObjectsV2
打印对象列表
我已经确认代码正在读取某些内容,因为如果我指向文件的非 GZIP 版本,它会抱怨该文件未压缩。
我的沙盒存储桶是私有的,并且具有最小存储桶策略:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::kkevin-testbucket",
"arn:aws:s3:::kkevin-testbucket/*"
],
"Condition": {
"StringEquals": {
"aws:PrincipalAccount": "123456789064"
}
}
}
]
}
编辑:我可以确认此 CLI 命令也可以工作并生成正确的输出:
aws s3api select-object-content \
--bucket kkevin-testbucket \
--key testfile.json.gz \
--expression "select * from s3object limit 5" \
--expression-type 'SQL' \
--input-serialization '{"JSON": {"Type": "Document"}, "CompressionType": "GZIP"}' \
--output-serialization '{"JSON": {}}' "output.json" \
--profile sandbox
您的代码是正确的。我在您的
S3SelectObjectContent
函数中添加了一些打印语句,如下
stream := result.GetStream()
defer stream.Close()
for event := range stream.Events() {
v, ok := event.(*types.SelectObjectContentEventStreamMemberRecords)
if ok {
value := string(v.Value.Payload)
fmt.Print(value)
}
}
if err := stream.Err(); err != nil {
return nil, err
}
我得到了以下输出
{"Name":"Kevin","Role":"engineer","Color":"blue"}