Python UDF 开发

更新时间:
复制 MD 格式

Python UDF 开发用于应对 SQL 内置函数无法表达的自定义计算场景。通过在客户端内完成编写、语法检查、本地调试、依赖打包与注册发布的完整闭环,可有效避免在本地装环境、手工打包上传、反复提交作业试错,满足数据开发者快速交付自定义函数的需求。

功能概述

UDF(User Defined Function,用户自定义函数)是 MaxCompute 提供的扩展机制,用于在 SQL 中调用自定义计算逻辑。客户端把这套流程集成在一个工作台里:左侧管理 UDF 草稿,中间是代码编辑器,下方面板承载数据预览、SQL 验证、依赖、调试、注册和历史。

草稿在本地保存,只有单击注册到 ODPS(ODPS 是 MaxCompute 的服务端标识,客户端界面沿用该名称)后才会正式发布到 MaxCompute 项目,因此可以在本地反复修改和调试。

python-udf-development-guide-zh

适用场景

  • 字段清洗与标准化:手机号脱敏、地址归一、编码转换等逐行处理逻辑,用 SQL 表达式编写冗长且不易维护。

  • 业务规则封装:将风控评分、标签判定等规则封装为函数,供多个 SQL 作业复用。

  • 复杂解析:解析 JSON、日志串、半结构化文本,将单行输入拆分为多行或多列输出。

  • 借助第三方库计算:引入 Python 第三方包,实现内置函数无法覆盖的计算能力。

功能索引

功能类别

功能项

草稿管理

新建 UDF、删除草稿、加入 AI 对话、复制名称

代码编写

Python 语法高亮、自动生成函数骨架、UDF / UDTF / UDAF 三种类型

校验与调试

语法检查、本地调试(真实表数据采样)、SQL 验证

依赖管理

添加 Python 依赖、复用项目资源

发布

注册到 ODPS、注册后校验、强制覆盖、注销

记录

编译历史、调试历史

AI 协作

编辑器内 AI 生成与修复、AI Query(自然语言数据分析对话)委派开发、发布前人工确认

前提条件

已创建并成功连接一个 MaxCompute 数据源,且已选定项目。UDF 入口依赖活动连接,未连接时不可用。

快速入门

以下步骤演示如何新建一个字符串转大写的 UDF 并发布到 MaxCompute。

  1. 在侧边栏 UDF 区域单击 +(或在统一新建对话框中选择 UDF 类型)。

  2. 在对话框中填写:

    • 函数名:输入 str_upper

    • 类型:保留默认 UDF

    • 参数签名:保留默认的一个 STRING 输入与一个 STRING 输出。

    • 上下文表(可选):选择一张用于调试的表,后续调试和 SQL 验证会自动带出表名与列名。

  3. 单击创建。客户端会生成函数骨架并打开编辑器,把 evaluate 的返回值改为 a.upper()

  4. 单击顶部语法检查。状态区显示语法检查通过表示代码可编译。

  5. 切换到下方调试标签,确认表名输入列已填好,单击运行调试,在结果表格中核对输出。

  6. 单击顶部注册到 ODPS。等待阶段提示走完预检查上传资源创建函数持久化,状态区显示注册成功即完成发布。

编写 UDF

函数类型与骨架

创建草稿时选择的类型决定生成的代码骨架:

类型

说明

生成的基类与方法

UDF

一行输入对应一行输出

普通类,实现 evaluate

UDTF

一行输入可产生多行输出

继承 BaseUDTF,实现 process,通过 self.forward() 输出

UDAF

多行输入聚合为一个结果

继承 BaseUDAF,实现 new_bufferiteratemergeterminate

UDF 类型生成的骨架如下,函数签名由创建时填写的参数签名决定:

from odps.udf import annotate

@annotate('string -> string')class str_upper(object):
    def __init__(self):
        passdef evaluate(self, a):
        return a

UDTF 需要在参数签名中通过添加输出列声明多个输出列。

编辑器与状态提示

编辑器基于 Monaco,提供 Python 语法高亮、括号配对着色与自动换行。代码修改会自动暂存,无需手动保存。

编辑器顶部会根据草稿与 MaxCompute 的一致性给出提示:

  • 从未注册过:提示当前草稿尚未注册到 ODPS,单击注册到 ODPS 即可发布。

  • 已注册但代码又被修改:黄色警告条提示「代码已修改,ODPS 上运行的仍是上次注册的版本」。此时线上函数仍是旧逻辑,需重新注册才生效。

上下文表

在顶部栏单击选择表可以为草稿绑定一张上下文表。绑定后:

  • Data 标签展示该表的列名、类型、分区标识与注释,并可预览数据。

  • 调试标签自动填入表名,并带出前 10 个非分区列作为输入列。

  • SQL 标签生成的验证语句自动引用该表。

单击表名旁的 × 可解除绑定。

草稿列表的状态标识

侧边栏的草稿列表会用两个标识提示草稿状态:

  • 名称后的 UDTF 或 UDAF 徽标:标明非普通 UDF 类型,普通 UDF 不显示徽标。

  • 名称后的黄色圆点:表示代码已修改但尚未重新注册。

在草稿上单击右键可以加入聊天(把代码作为附件送给 AI)、复制名称删除

本地调试

本地调试是在机器上用真实表数据跑一遍 UDF,不提交 MaxCompute 作业,因此不消耗计算资源。

  1. 切换到下方调试标签。

  2. 填写调试参数:

    • 表名:格式为 <project_name>.<table_name>

    • 输入列:多个列以英文逗号分隔,按顺序对应函数入参。

    • 分区(可选):格式为 ds=20260101/hh=00

    • 采样行数:默认 100 行,最大 1000 行。

  3. 单击运行调试。执行过程依次经过 Python 语法预检采样输入执行 UDF 三个阶段,运行中可单击停止按钮中断。

  4. 查看结果。结果区显示结果行数、退出码与耗时,输出以表格逐行呈现;标准错误可展开查看 print 与异常堆栈,便于定位问题。

调试结束状态包括成功失败超时内存溢出占用本机内存过高被终止已取消。后两种状态说明采样数据或函数内存占用过大,建议减少采样行数后重试。

依赖管理

在下方依赖标签的 Python wheels 页可以为 UDF 添加第三方库。

  1. 在输入框填写依赖声明,例如 numpy==1.26.4

  2. 单击添加。客户端会从 PyPI 解析并下载 wheel 包,同时下载适配服务端与本地调试的两份产物。

  3. 添加成功后依赖出现在列表中,并自动注入到源码的 sys.path,代码中直接 import 即可。

若项目中已有其他草稿上传过资源,可单击复用项目资源直接选用,避免重复上传。

常见失败原因:

  • 该依赖仅提供平台相关的编译 wheel,PyPI 上没有可用于服务端的版本。

  • 该包只发布了源码包(sdist),没有任何二进制 wheel。

  • 包名拼写有误。

以上情况说明该依赖不属于纯 Python 包,请改用等价的纯 Python 实现,或参照 MaxCompute 官方文档手动上传资源。

注册到 MaxCompute

执行注册

单击顶部注册到 ODPS,或在下方注册标签中确认资源清单后再发布。注册按以下阶段推进,状态区会实时显示进度:

  1. 预检查:校验草稿完整性并计算需要上传的资源清单。

  2. 上传资源:把代码与依赖上传为 MaxCompute 资源,显示 已上传/总数 计数。

  3. 创建函数:执行 CREATE FUNCTION

  4. 校验(可选):勾选注册后校验时执行,见下文。

  5. 持久化:记录注册结果,编辑器的未注册提示随之消失。

注册标签同时展示本次要发布的函数名、语言、资源清单(类型、路径、大小、sha256),发布前可核对。

注册后校验

注册后校验默认关闭。勾选后,客户端会在 MaxCompute 上提交一条冒烟查询,确认函数能够正常加载。

该校验会提交真实作业,耗时较长并产生计算费用,但能提前暴露「注册成功却调用失败」的问题,建议在正式交付前至少执行一次。

校验覆盖两个运行时:先用 Python 3.11(cp311)验证,再用服务端默认的 Python 2.7(cp27)验证。若后者未通过,注册仍会保留,但会给出警告,提示不带 cp311 声明的裸 SQL 调用可能失败。

处理同名冲突

若 MaxCompute 上已存在同名资源或函数,注册会失败并提示 ODPS 上已存在同名函数。此时可以:

  • 单击强制覆盖,用当前草稿覆盖线上的同名资源与函数。

  • 或取消本次注册,改用其他函数名重新创建草稿。

重要

强制覆盖会直接替换线上正在使用的函数实现,可能影响依赖该函数的线上作业。请确认影响范围后再执行。

在 SQL 中调用

注册完成后即可在 SQL 中调用。由于服务端默认运行时为 cp27,建议显式声明运行时版本:

SET odps.sql.python.version=cp311;
SELECT str_upper(name) FROM <project_name>.<table_name> LIMIT 10;

下方 SQL 标签提供了同样的验证入口:它会生成一条引用上下文表的查询语句,运行时自动在语句前追加 SET odps.sql.python.version=cp311;,可直接单击运行查看结果与 Logview。

注销

注册标签单击注销可从 MaxCompute 移除该函数的注册。本地草稿仍会保留。

用 AI 开发 UDF

客户端提供两种 AI 协作方式,按所处的界面选择即可。

方式一:在 UDF 编辑器内让 AI 写

打开 UDF 草稿后,在 AI 对话侧栏直接用自然语言描述需求,例如「把身份证号中间 8 位替换成星号」。AI 会读取当前草稿,给出改动并等待确认。

输入框支持两类快捷输入:

  • 输入 @ 引用上下文,例如把某张表的结构带给 AI。

  • 输入 / 调用命令,共 4 条:

    命令

    作用

    /build

    编译 / 语法检查

    /register

    注册 UDF 到 ODPS

    /debug

    本地调试 UDF

    /kill

    强制释放会话锁

涉及改动或发布的操作会先弹出审批卡,批准后才执行,拒绝则中止:

  • 改写整份源码:以差异对比形式展示改动内容。

  • 局部修补源码:展示补丁内容。

  • 添加依赖、执行本地调试、采样表数据、执行 SQL、注册 UDF:展示对应参数。

方式二:在 AI Query 中委派开发

在 AI Query 对话中直接提出带 UDF 的需求,例如「写一个把手机号脱敏的 UDF,注册后统计各城市的去重用户数」。AI 会判断这是一项编程任务,交给专门的 UDF 子任务完成,无需指定工具或步骤。

过程中会看到:

  1. 自动打开编辑器。子任务写出初版代码时,客户端自动打开该草稿的编辑器标签页,后续每次改写都会同步刷新,支持随时查看进展,也可以直接接手修改。

  2. 开发面板中的进度。AI Coding 面板(展示子任务执行过程的侧边面板)按时间线记录 UDF 草稿UDF 代码更新UDF 已发布 等节点,语法检查失败时 AI 会自行修复并重新检查。

  3. 发布前的人工确认。卡片内容形如「请确认发布 UDF「xxx」到 ODPS 项目 xxx。确认后才会执行 CREATE FUNCTION」。

  4. 右侧栏的产物入口。子任务列表中会留下该草稿的入口,单击即可回到编辑器。