首页 > 解决方案 > 将 AWS S3 Select 与适用于 Ruby 的 AWS 开发工具包一起使用时出现编码错误

问题描述

我正在尝试执行以下操作:

我总是收到以下错误,总是“接近字节 8192”,即使内容file.csv.gz完全不同:

Aws::S3::Errors::InvalidTextEncoding (UTF-8 encoding is required. The text encoding error was found near byte 8,192.)

注意:对相同的未压缩file.csv工作使用相同的 S3 Select 查询。我尝试过各种奇怪的事情,但我充满了绝望。

重现步骤:

  1. 从文件开始s3://mybucket/file.csv
  2. 使用 aws-cli 下载:aws s3 cp s3://mybucket/file.csv file.csv
  3. 压缩文件:gzip file.csv
  4. 上传file.csv.gzaws s3 cp file.csv.gz s3://mybucket/file.csv.gz

这是代码:

class RunsS3SelectQueries
  def self.client
    @client ||= Aws::S3::Client.new
  end

  def self.run_query(sql:, bucket:, key:)
    data = ""
    handler = Aws::S3::EventStreams::SelectObjectContentEventStream.new
    handler.on_records_event do |event|
      puts "----records payload:----"
      payload = event.payload.read
      data += payload
    end
    handler.on_stats_event do |event|
       # get :stats event that contains progress information
       puts event.details.inspect
       # => Aws::S3::Types::Stats bytes_scanned=xx, bytes_processed=xx, bytes_returned=xx
    end
    params = {
      bucket: bucket,
      key: key,
      expression_type: "SQL",
      expression: sql,
      input_serialization: {
        csv: { file_header_info: "USE"}
      },
      output_serialization: {
        csv: {}
      },
      event_stream_handler: handler,
    }
    client.select_object_content(params)
    data
  end
end

以下收到文本编码错误。

output = RunsS3SelectQueries.run_query(sql: %q{SELECT * FROM S3Object }, bucket: 'mybucket', key: 'file.csv.gz')

但是,针对未压缩的运行file.csv不会:

output = RunsS3SelectQueries.run_query(sql: %q{SELECT * FROM S3Object }, bucket: 'mybucket', key: 'file.csv')

我尝试了各种文本编码、内容类型元数据、内容编码等的组合,但似乎找不到任何有效的方法。在我看来,它总是在字节 8192 上出现错误的事实非常奇怪/可疑。

任何帮助将非常感激!

标签: aws-sdk-rubyamazon-s3-select

解决方案


您需要指定输入已被 gzip 压缩input_serialization,否则 s3 将尝试解码 gzip 标头,并在字节 8192 处收到关于它不是有效的 utf-8 的错误。

像下面这样的东西会起作用:

input_serialization: { csv: { file_header_info: "USE"} CompressionType: "GZIP" }


推荐阅读