aws-sdk-ruby - 将 AWS S3 Select 与适用于 Ruby 的 AWS 开发工具包一起使用时出现编码错误
问题描述
我正在尝试执行以下操作:
- 从 S3 下载 Athena 查询的输出 (
file.csv
) - gzip 输出并上传到不同的 S3 位置 (
file.csv.gz
) - 在 Ruby SDK 中使用 S3 Select 来查询
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.)
注意:对相同的未压缩file.csv
工作使用相同的 S3 Select 查询。我尝试过各种奇怪的事情,但我充满了绝望。
重现步骤:
- 从文件开始
s3://mybucket/file.csv
- 使用 aws-cli 下载:
aws s3 cp s3://mybucket/file.csv file.csv
- 压缩文件:
gzip file.csv
- 上传
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 上出现错误的事实非常奇怪/可疑。
任何帮助将非常感激!
解决方案
您需要指定输入已被 gzip 压缩input_serialization
,否则 s3 将尝试解码 gzip 标头,并在字节 8192 处收到关于它不是有效的 utf-8 的错误。
像下面这样的东西会起作用:
input_serialization: {
csv: { file_header_info: "USE"}
CompressionType: "GZIP"
}
推荐阅读
- javascript - 传递图标参数时,标记加载时间慢 10 倍(有效与否)
- c# - Roslyn:如何在不同项目中对上下文进行代码修复?
- java - 如何在使用junit测试的方法中验证存储库是否被调用n次?
- python - 如何使用 deep-deep 项目?
- intellij-idea - IntelliJ Glassfish5 JAX-RS 路径不起作用
- kotlin - 当 BooleanArray 中的所有布尔值都为真时,Kotlin 如何调用方法
- android - 在非常有限的情况下允许来自 Android 应用的明文 HTTP 流量
- jquery - 基于复选框添加/删除类
- authentication - IIS 和 Windows 身份验证出现错误 401
- asp.net-core - 如何在禁用根路径访问的同时设置 ASP.NET Core 应用程序的基本路径?