Ошибка кодирования при использовании aws s3 select с aws sdk для ruby

Я пытаюсь сделать следующее:

  • загрузить вывод запроса Athena из S3 (file.csv)
  • заархивируйте вывод и загрузите в другое место S3 (file.csv.gz)
  • используйте S3 Select из Ruby SDK для запроса содержимого file.csv.gz

Я всегда получаю следующую ошибку, всегда «около байта 8192», даже если содержимое file.csv.gz совершенно другое:

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

NB: использование того же запроса S3 Select для того же несжатого file.csv работает должным образом. Я перепробовал разные странные вещи, но полон отчаяния.

Действия по воспроизведению:

  1. Начнем с файла s3://mybucket/file.csv
  2. Скачать с aws-cli: aws s3 cp s3://mybucket/file.csv file.csv
  3. Заархивируйте файл: 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, на мой взгляд, довольно странный / подозрительный.

Любая помощь приветствуется!

1
0
2 879
1

Ответы 1

Вам необходимо указать, что входные данные заархивированы в input_serialization, иначе s3 попытается декодировать заголовок gzip и получит сообщение об ошибке, что он недействителен utf-8 в байте 8192.

Что-то вроде следующего будет работать:

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

Другие вопросы по теме