Как использовать select_object_content через rusoto / rust?
Следующий код пытается выбрать некоторые данные из файла, хранящегося на 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()
};
Это вызывает следующую ошибку:
Указанный метод не разрешен для этого ресурса.
Примером является порт 1:1 рабочего примера Python/boto3, поэтому я вполне уверен, что он должен работать. Я обнаружил эту проблему, которой уже несколько месяцев, и статус которой мне не ясен. Как мне заставить это работать с Rust?
1 ответ
К сожалению s3 select все еще не работает на последней rusoto_s3-0.40.0
, У проблемы, которую вы связали, есть все ответы. Проблемы двоякие.
Во-первых, прямо сейчас запрос выбора s3 rusoto
отсылает имеет поддельную строку запроса. Так должно быть /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
просто еще нет десериализатора для этого.