我很难让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
}

提前感谢您的帮助和建议.

我试着调整了bucketobjectKey...如果这些是不正确的,我会得到一个"找不到".

我已经确认我有权访问存储桶,因为我能够使用ListObjectsV2打印对象列表

我已经确认代码正在读取某些内容,因为如果我指向文件的非GZIP版本,它会抱怨文件没有压缩.

我的Sandbox 存储桶是私有的,并且具有最低存储桶策略:

{
    "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"}

Go相关问答推荐

Go汇编器命名为Constants

gorm插入不支持的数据

未对GoFr中的所有请求进行跟踪

为什么要立即调用内联函数,而不仅仅是调用其包含的函数?

如何使用 Go 连接到非默认 firestore 数据库?

这种合并排序的实现有什么问题?

如何在 Go 中编写示例测试?

Go泛型:无效的复合文字

Go:从 ssl 证书中获取 'subject/unstructeredName' 的值

在 Go 模板中对照片使用随机 Int

使用innerxml在 Go 中编码 XML 是否仅适用于某些类型?

如何将具有嵌入式 struct 的 struct 展平为 json

级联调用泛型函数时的泛型类型推断

在 go 中将运行命令的标准输出发送到其标准输入

如何在Go中替换符号并使下一个字母大写

有没有办法判断值是否满足接口中定义的类型约束?

如何通过组合来自不同包的接口来创建接口?

在 golang 中联合一个接口和类型

实现接口的指针的泛型类型是什么?

如何在 Prometheus 中正确检测区域和环境信息?