1

以下代码尝试从存储在 S3 上的文件中选择一些数据:

  let client = S3Client::new(Region::default());
  let source = ... object providing bucket and key ...;

  let r = SelectObjectContentRequest {
      bucket: source.bucket,
      key: source.key,
      expression: "select id from S3Object[*].id".to_string(),
      expression_type: "SQL".to_string(),
      input_serialization: InputSerialization {
          json: Some(JSONInput { type_: Some("LINES".to_string()) }),
          ..Default::default()
      },
      output_serialization: OutputSerialization {
          json: Some(JSONOutput { record_delimiter: Some("\n".to_string()) }),
          ..Default::default()
      },
      ..Default::default()
  };

它会导致以下错误:

不允许针对此资源使用指定的方法。POST

该示例是一个工作 Python/boto3 示例的 1:1 端口,所以我很确定它应该可以工作。我发现了这个问题,这是几个月前的问题,我不清楚状态。我如何让这个与 Rust 一起工作?

4

1 回答 1

0

不幸的是 s3 select 仍然不能在最新的rusoto_s3-0.40.0. 您链接的问题有所有答案。问题是双重的。

首先,现在rusoto发出的 s3 选择请求有一个虚假的查询字符串。它应该是/ObjectName?select&select-type=2,但rusoto将其编码为/bjectName?select%26select-type=2。这就是你看到的错误。

要验证,请像这样运行您的项目:

$ RUST_LOG=rusoto,hyper=debug cargo run

rusoto您将看到来自和的日志hyper。果然它发出了一个不正确的 URI。甚至可以深入研究负责的代码

let mut params = Params::new();
params.put("select&select-type", "2");
request.set_params(params);

它应该是:

let mut params = Params::new();
params.put("select-type", "2");
params.put("select", "");
request.set_params(params);

尽管修复看起来微不足道,但请记住,这些是从 AWS botocore 服务清单生成的胶水代码,而不是手动编码。合并修复并不是那么简单。

第二,更大的问题。AWS s3 select 响应使用自定义的二进制格式rusoto根本还没有反序列化器。

于 2019-08-26T12:22:43.927 回答