Ошибка кодирования при использовании 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.)

Примечание: использование одного и того же запроса 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, на мой взгляд, довольно странный / подозрительный.

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

0 ответов

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

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

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

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