1

私は次のことをしようとしています:

  • S3 から Athena クエリの出力をダウンロードする ( file.csv)
  • 出力を gzip し、別の S3 の場所にアップロードします ( file.csv.gz)
  • Ruby SDK 内から S3 Select を使用して、file.csv.gz

file.csv.gz内容が完全に異なる場合でも、常に次のエラーが発生します。常に「8192バイト近く」です。

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

注意: 同じ非圧縮に対して同じ S3 Select クエリを使用すると、file.csv期待どおりに動作します。私はあらゆる種類の奇妙なことを試みましたが、絶望に満ちています。

再現する手順:

  1. ファイルから開始s3://mybucket/file.csv
  2. aws-cli でダウンロードします。aws s3 cp s3://mybucket/file.csv file.csv
  3. ファイルを gzip します。gzip file.csv
  4. アップロードfile.csv.gz:aws 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 で常にエラーが発生するという事実は、かなり奇妙で疑わしいものです。

どんな助けでも大歓迎です!

4

1 に答える 1