写点什么

Databend UDF 的 StageLocation 支持

作者:Databend
  • 2025-12-23
    福建
  • 本文字数:2086 字

    阅读完需:约 7 分钟

Databend UDF的StageLocation支持

作者: KKould

Stage 是 Databend 中最常用的“落地/共享”存储形态:无论是从对象存储导入数据,还是把查询结果导出给下游,几乎都要经过 Stage。借助 PR feat: External UDF support STAGE_LOCATION param #18833,外部 UDF 现在可以以 STAGE_LOCATION 形式直接获取 Stage 元数据,避免手动拼接/解析路径,让自定义逻辑与对象存储无缝衔接。

设计目标与收益

  • 目标:在 SQL 中直接传入 @stage/path,解析后生成结构化 Stage 元数据,运行时注入到 UDF;STAGE_LOCATION 类型显式声明依赖,便于校验与文档化。

  • 对 Databend Query 的价值:解析 Stage literal,校验仅允许 External Stage 且需独立凭证;在物理计划中剥离 Stage 参数,只通过 databend-stage-mapping header 传递元数据,保持数据列纯净。

  • 对外部 UDF Server 的价值:装饰器 stage_refs 明确 Stage 形参,StageLocation 对象直接提供 storagerelative_pathraw_info 等字段,函数无需自写解析或处理敏感凭证。

  • 安全:拒绝内部 Stage、IAM Role、STS 等高权限路径;非法 Stage 在执行前即被拦截,降低泄露风险。

基本 Stage 使用

Stage 是 Databend 的虚拟存储位置,支持内部和外部对象存储,让数据能方便地进出 Databend。


-- 创建外部 StageCREATE STAGE my_external_stage    URL = 's3://databend-doc'    CONNECTION = (        AWS_KEY_ID = '<您的密钥ID>',        AWS_SECRET_KEY = '<您的密钥>'    );
LIST @my_external_stage;
复制代码


在明确文件格式时,可以直接查询 Stage 数据:


CREATE STAGE parquet_query_stage URL = 's3://load/parquet/' CONNECTION = (    ACCESS_KEY_ID = '<your-access-key-id>'     SECRET_ACCESS_KEY = '<your-secret-access-key>');
CREATE FILE FORMAT parquet_query_format TYPE = PARQUET;
SELECT $1FROM @parquet_query_stage( FILE_FORMAT => 'parquet_query_format', PATTERN => '.*[.]parquet');
复制代码

在 UDF 中使用 STAGE_LOCATION

过去需要把 Stage 路径当字符串传给 UDF,再手动解析;现在可以在 SQL 中直接声明 STAGE_LOCATION,在 Python 侧用装饰器列出 Stage 形参即可获取 StageLocation 对象。


@udf(stage_refs=["stage_loc"], input_types=["INT"], result_type="INT")def gcd(stage: StageLocation, value):    bucket_cfg = stage.storage      # 已解析的外部存储配置    working_path = stage.relative_path    ...
复制代码


CREATE OR REPLACE FUNCTION gcd (    stage_loc STAGE_LOCATION,    a INT,    b INT)RETURNS INTLANGUAGE pythonHANDLER = 'gcd'ADDRESS = 'http://127.0.0.1:8815';
SELECT gcd(@gcd_stage/input/2024/, 21, 14);
复制代码


StageLocation 字段示例:


class StageLocation:    name: str          # SQL 传入的 @path 全量值    stage_name: str    # Stage 名称    stage_type: str    # 仅 External Stage 被接受    storage: Dict[str, Any]     # 已解析的存储配置 (无 IAM Role/STS)    relative_path: str          # 相对路径部分    raw_info: Dict[str, Any]    # 完整元数据备查
复制代码

最终用户体验

  • 单 Stage:


CREATE OR REPLACE FUNCTION gcd (    STAGE_LOCATION stage_loc,    INT a,    INT b) RETURNS INTLANGUAGE pythonHANDLER = 'gcd'ADDRESS = 'http://127.0.0.1:8815';
SELECT gcd(@gcd_stage/input/2024/, 21, 14);
复制代码


  • 多 Stage:


CREATE OR REPLACE FUNCTION process_data (    STAGE_LOCATION input_stage,    STAGE_LOCATION output_stage,    INT batch_id) RETURNS INTLANGUAGE pythonHANDLER = 'process_data'ADDRESS = 'http://127.0.0.1:8815';
SELECT process_data(@raw_stage/2024/05/, @result_stage/2024/05/, 42);
复制代码


  • 行为对照:

  • External Stage + 独立凭证:✅ 正常执行。

  • Internal/User/Legacy Stage:❌ 拒绝,提示“仅支持 External Stage”。

  • External Stage 使用 IAM Role / STS:❌ 拒绝,要求改用独立 AK/SK。

工作原理简述

  • Databend 解析 SQL 中的 @stage/path,校验仅支持 External Stage 且需独立凭证,生成 StageLocation 元数据。

  • 执行计划里 Stage 参数被剥离,元数据通过 databend-stage-mapping header 传到 UDF Server,数据列按原样传递。

  • Python 侧 stage_refs 自动解析该 header 并注入 StageLocation 对象,用户代码无需再解析或处理敏感凭证。

安全界限

  • Stage literal 必须以 @ 起始;解析失败或非 External Stage 直接报错。

  • 禁止 IAM Role、STS 临时凭证,要求使用独立 AK/SK;调用方仍需拥有 Stage 访问权限。

  • 外部服务不应打印或泄露 StageLocation.storage 中的敏感字段,日志需做脱敏处理。

关于 Databend

Databend 是一款 100% Rust 构建、面向对象存储设计的新一代开源云原生数据仓库,统一支持 BI 分析、AI 向量、全文检索及地理空间分析等多模态能力。期待您的关注,一起打造新一代开源 AI + Data Cloud。👨‍💻‍ Databend Cloud:https://databend.cn


📖 Databend 文档:https://docs.databend.cn


💻Wechat:Databend


✨GitHub:https://github.com/databendlabs/databend


发布于: 刚刚阅读数: 3
用户头像

Databend

关注

还未添加个人签名 2022-08-25 加入

还未添加个人简介

评论

发布
暂无评论
Databend UDF的StageLocation支持_Databend_InfoQ写作社区