lakeFS Rust SDK 的 UploadPartCopyFrom 模型:预签名分片复制(Multipart Upload Copy Part)请求体详解

发布时间:2026/10/14 15:51:14
lakeFS Rust SDK 的 UploadPartCopyFrom 模型:预签名分片复制(Multipart Upload Copy Part)请求体详解 数据工程数据湖大数据对象存储后端【免费下载链接】lakeFSlakeFS - Data version control for your data lake | Git for data项目地址https://gitcode.com/gh_mirrors/la/lakeFS点击查看免费下载导读UploadPartCopyFrom是 lakeFS Rust SDK 中用于预签名分片上传复制presigned multipart upload copy的请求体模型它描述如何把另一个对象的某一段字节复制为当前分片上传的一个 part。本文以 UploadPartCopyFrom.md 为核心结合 Rust 模型源码、OpenAPI 定义api/swagger.yml、服务端控制器实现pkg/api/controller.go以及端到端测试esti/presign_multipart_test.go完整讲解该模型的字段语义、它与CopyPartSource的嵌套关系、底层upload_part_copy接口的调用链并给出可直接运行的 Rust 代码示例。模型概览UploadPartCopyFrom 是什么UploadPartCopyFrom对应 HTTP 接口PUT /repositories/{repository}/branches/{branch}/staging/pmpu/{uploadId}/parts/{partNumber}/copy的 JSON 请求体其作用是在 lakeFS 的预签名分片上传流程中通过服务端复制而非上传字节的方式填充一个分片part。它由 openapi-generator 根据api/swagger.yml自动生成仓库中的 Rust 实现位于 src/models/upload_part_copy_from.rs。原文档给出的字段定义如下NameTypeDescriptionNotesphysical_addressStringThe physical address (of the entire intended object) returned from createPresignMultipartUpload.copy_sourcemodels::CopyPartSource从 OpenAPI 定义api/swagger.yml可以看出UploadPartCopyFrom并不是一个独立的平铺结构而是通过allOf继承UploadPartFrom该父模型只包含physical_address字段再追加copy_source字段UploadPartCopyFrom: allOf: # Extend UploadPartFrom - $ref: #/components/schemas/UploadPartFrom - type: object properties: copy_source: description: Source of copy $ref: #/components/schemas/CopyPartSource required: - copy_source生成的 Rust 结构体与之一一对应upload_part_copy_from.rs#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] pub struct UploadPartCopyFrom { /// The physical address (of the entire intended object) returned from createPresignMultipartUpload. #[serde(rename physical_address)] pub physical_address: String, #[serde(rename copy_source)] pub copy_source: Boxmodels::CopyPartSource, }字段语义physical_addressphysical_address是目标对象整个分片上传的物理地址必须取自createPresignMultipartUpload即POST /repositories/{repository}/branches/{branch}/staging/pmpu接口的响应PresignMultipartUpload.physical_address见 swagger.yml。它把本次复制要写入哪个上传会话锚定在分片上传上而不是每次复制都重新指定目标。服务端在 pkg/api/controller.go 中会对其做两重校验通过normalizePhysicalAddress判断其地址类型必须是相对存储命名空间AddressTypeRelative的相对地址否则返回 400调用Catalog.VerifyLinkAddress验证该地址已经为链接而保存即该物理地址属于本次分片上传注册过的地址防止把任意物理地址写入分片。嵌套模型CopyPartSourcecopy_source描述从哪个对象、哪个区间复制字节。其 Rust 实现位于 src/models/copy_part_source.rs对应文档 CopyPartSource.md字段如下NameTypeDescriptionNotesrepositoryString源对象所在仓库r#refString源对象所在引用分支、tag 或 commit IDpathString源对象在引用下的路径rangeOptionString要复制的字节区间[optional]其中range的可选值是带模式校验的字符串在 api/swagger.yml 中定义为range: description: Range of bytes to copy type: string pattern: ^bytes((\d*-\d*,? ?))$即必须形如bytesstart-end如bytes0-4194303。注意该区间是闭区间inclusive——测试 esti/presign_multipart_test.go 中的注释明确指出 the Range header isinclusive. So this drops the last byte也就是说想复制第 1 到第 N-1 字节需写bytes1-(N-2)。由于r#ref中的ref是 Rust 关键字生成的字段名为r#ref使用原始标识符语法访问copy_source.r#ref。而CopyPartSource::new构造函数只要求repository、ref、path三个必填参数range通过Option留空copy_part_source.rspub fn new(repository: String, r#ref: String, path: String) - CopyPartSource { CopyPartSource { repository, r#ref, path, range: None, } }服务端复制语义range 有无决定了两种底层调用服务端处理uploadPartCopy时controller.go会根据copy_source.range是否设置分派到块存储适配器的两个不同接口未设置 range调用c.BlockAdapter.UploadCopyPart(ctx, srcObjectRef, dstObjectRef, uploadID, partNumber)即把源对象的整个内容作为一个 part 复制设置 range用fmt.Sscanf(*rng, bytes%d-%d, startPosition, endPosition)解析起止位置后调用c.BlockAdapter.UploadCopyPartRange(ctx, srcObjectRef, dstObjectRef, uploadID, partNumber, startPosition, endPosition)实现只复制源对象的一段字节。这里的srcObjectRef通过Catalog.GetEntry先从源仓库/引用/路径解析出源 entry再取其PhysicalAddress构造controller.go。复制成功后接口返回204 No Content并在响应头ETag中给出该 part 的 ETag——这个 ETag 正是后续completePresignMultipartUpload组装分片时需要提交的内容见 swagger.yml 中 ETag of the uploaded part, pass in completion。此外该接口的鉴权要求是同时满足两个权限节点NodeTypeAnd见 controller.go对目标路径的WriteObjectAction以及对源路径的ReadObjectAction。这意味着复制操作天然需要写目标 读源的双重授权。前置流程presign 分片上传的完整生命周期UploadPartCopyFrom只是预签名分片上传链路中的一环。结合 ExperimentalApi.md 与 swagger.yml完整的生命周期为createPresignMultipartUploadPOST /repositories/{repository}/branches/{branch}/staging/pmpu初始化分片上传返回PresignMultipartUpload——包含upload_id、physical_address以及可选的presigned_urls数组见 PresignMultipartUpload.md。part 编号从 1 开始除最后一个 part 外每个 part 有最小大小限制取决于底层块存储实现例如 S3 块存储下为 5MB。upload_part / upload_part_copyPUT .../parts/{partNumber}与PUT .../parts/{partNumber}/copy逐个填充 part。前者返回一个用于直传的预签名 URL后者通过UploadPartCopyFrom实现服务端复制。注意part_number的取值范围为 1 到 10000见 swagger.yml。completePresignMultipartUploadPUT .../pmpu/{uploadId}提交CompletePresignMultipartUpload包含按升序排列的parts列表、physical_address、可选的user_metadata与content_type服务端把各个 part 组装成最终对象见 swagger.yml。Rust SDK 中对应的异步函数签名位于 src/apis/experimental_api.rspub async fn upload_part_copy( configuration: configuration::Configuration, repository: str, branch: str, upload_id: str, path: str, part_number: i32, upload_part_copy_from: models::UploadPartCopyFrom, ) - Result(), ErrorUploadPartCopyError其构造的请求 URL 为{base_path}/repositories/{repository}/branches/{branch}/staging/pmpu/{uploadId}/parts/{partNumber}/copy请求体以 JSON 序列化UploadPartCopyFrom发送成功时返回空响应体204 No Content。Rust 实战示例复制源对象的一段字节作为 part下面这段示例演示如何在 Rust SDK 中构造UploadPartCopyFrom把main分支下large_data.bin的第 1 至第 N-2 字节复制为分片上传的第 1 个 part边界取自仓库端到端测试 esti/presign_multipart_test.go 的复制用例use lakefs_sdk::models::{CopyPartSource, UploadPartCopyFrom}; use lakefs_sdk::apis::{configuration::Configuration, experimental_api}; let config Configuration::new(); // 1. 初始化预签名分片上传 let resp_create experimental_api::create_presign_multipart_upload( config, my-repo, main, dest/data.bin, Some(2), ).await?; let upload_id resp_create.upload_id; let physical_address resp_create.physical_address; // 2. 构造复制请求体复制源对象的一个字节区间闭区间 let copy_from UploadPartCopyFrom { physical_address: physical_address.clone(), copy_source: Box::new(CopyPartSource { repository: my-repo.to_string(), r#ref: main.to_string(), path: large_data.bin.to_string(), range: Some(format!(bytes1-{}, large_data_content_length - 2)), }), }; // 3. 执行复制part 编号从 1 开始 experimental_api::upload_part_copy( config, my-repo, main, upload_id, dest/data.bin, 1, copy_from, ).await?;之后继续用upload_part填充剩余 part最后一个 part 需由客户端实际上传再调用complete_presign_multipart_upload提交parts含每个 part 的 ETag完成组装最终对象即可通过stat_object校验其 checksum 与总大小参见 presign_multipart_test.go 的验证逻辑。使用场景与注意事项典型场景当目标对象的大部分数据与仓库内已有对象重合时例如对已有大文件做小范围修改后形成新对象可以只把修改产生的少量 part 用预签名 URL 直传其余 part 全部通过UploadPartCopyFrom走服务端复制从而大幅减少客户端到对象存储之间的数据传输。注意事项physical_address必须来自createPresignMultipartUpload的响应且必须是相对存储命名空间的地址否则服务端返回 400copy_source的repository/ref/path为必填range可选提供range时格式必须匹配^bytes((\d*-\d*,? ?))$且区间为闭区间复制操作需要同时对目标路径具备写权限、对源路径具备读权限该接口位于experimental标签下swagger.yml属于实验性 API接口形态可能随版本演进变化使用前建议以当前仓库的 api/swagger.yml 为准端到端测试 esti/presign_multipart_test.go 仅在块存储类型为 S3 时运行skipPresignMultipart判断ViperBlockstoreType ! s3即跳过说明该能力与底层块存储的 multipart copy 支持密切相关。参考路径汇总模型文档clients/rust/docs/UploadPartCopyFrom.md、clients/rust/docs/CopyPartSource.md、clients/rust/docs/PresignMultipartUpload.mdRust 模型源码clients/rust/src/models/upload_part_copy_from.rs、clients/rust/src/models/copy_part_source.rsAPI 函数实现clients/rust/src/apis/experimental_api.rs、clients/rust/docs/ExperimentalApi.mdOpenAPI 定义api/swagger.yml模型、api/swagger.yml接口服务端实现pkg/api/controller.go端到端测试esti/presign_multipart_test.go赞分享数据工程数据湖大数据对象存储后端【免费下载链接】lakeFSlakeFS - Data version control for your data lake | Git for data项目地址https://gitcode.com/gh_mirrors/la/lakeFS点击查看免费下载相关推荐lakeFS Python SDK 的 UploadPartFrom 模型预签名分片上传Presigned Multipart Upload的逐片上传请求体详解lakeFS Python SDK 的 UploadPartFrom 模型预签名分片上传Presigned Multipart Upload的逐片上传请求数据工程数据湖大数据对象存储后端lakeFS Java SDK 的 UploadPartCopyFrom 模型基于预签名分片上传的跨对象分片复制lakeFS Java SDK 的 UploadPartCopyFrom 模型基于预签名分片上传的跨对象分片复制 导读 本文深入讲解 lakeFS Java数据工程数据湖大数据对象存储后端lakeFS Rust SDK 的 AbortPresignMultipartUpload预签名分片上传中止请求模型完全解析lakeFS Rust SDK 的 AbortPresignMultipartUpload预签名分片上传中止请求模型完全解析 lakeFS 为数据湖提供 Gi数据工程数据湖大数据对象存储后端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询