如何制作可以在 MaxCompute 上使用的 crcmod

本文详述在MaxCompute环境中,如何针对缺乏预编译Wheel包的第三方库,如crcmod,利用quay.io/pypa/manylinux1_x86_64镜像制作兼容的Wheel包。通过修改setup.py支持Wheel格式,准备依赖项,编写打包脚本,并最终使用Docker进行打包。

之前我们介绍过在 PyODPS DataFrame 中使用三方包。对于二进制包而言,MaxCompute 要求使用包名包含 cp27-cp27m 的 Wheel 包。但对于部分长时间未更新的包,例如 oss2 依赖的 crcmod,PyPI 并未提供 Wheel 包,因而需要自行打包。本文介绍了如何使用 quay.io/pypa/manylinux1_x86_64 镜像制作可在 MaxCompute 上使用的 Wheel 包。

本文参考 https://github.com/pypa/manylinux ,quay.io/pypa/manylinux1_x86_64 镜像也是目前绝大多数 Python 项目在 Travis CI 上打包的标准工具,如有进一步的问题可研究该项目。

1. 准备依赖项

不少包都有依赖项,例如 devel rpm 包或者其他 Python 包,在打包前需要了解该包的依赖,通常可以在 Github 中找到安装或者打包的相关信息。对于 crcmod,除 gcc 外不再有别的依赖,因而此步可略去。

2. 修改 setup.py 并验证(建议在 Mac OS 或者 Linux 下)

较旧的 Python 包通常不支持制作 Wheel 包。具体表现为在使用 python setup.py bdist_wheel 打包时报错。如果需要制作 Wheel 包,需要修改 setup.py 以支持 Wheel 包的制作。对于一部分包,可以简单地将 distutils 中的 setup 函数替换为 setuptools 中的 setup 函数。而对于部分自定义操作较多的 setup.py,需要详细分析打包过程,这一项工作可能会很复杂,本文就不讨论了。

例如,对于 crcmod,修改 setup.py 中的

from distutils.core import setup

from setuptools import setup

即可。

修改完成后,在项目根目录执行

python setup.py bdist_wheel

如果没有报错且生成的 Wheel 包可在本地使用,说明 setup.py 已可以使用。

3. 准备打包脚本

在项目中新建 bin 目录,并在其中创建 build-wheel.sh:

mkdir bin && vim bin/build-wheel.sh

在其中填入以下内容:

#!/bin/bash
# modified from https://github.com/pypa/python-manylinux-demo/blob/master/travis/build-wheels.sh
set -e -x

# Install a system package required by our library
# 将这里修改为安装依赖项的命令

# Compile wheels
PYBIN=/opt/python/cp27-cp27m/bin
# 如果包根目录下有 dev-requirements.txt,取消下面的注释
# "${PYBIN}/pip" install -r /io/dev-requirements.txt
"${PYBIN}/pip" wheel /io/ -w wheelhouse/

# Bundle external shared libraries into the wheels
for whl in wheelhouse/*.whl; do
    auditwheel repair "$whl" -w /io/wheelhouse/
done

将第一步获知的依赖项安装脚本填入此脚本,在使用 python 或 pip 时,注意使用 /opt/python/cp27-cp27m/bin 中的版本。

最后,设置执行权限

chmod a+x bin/build-wheel.sh
4. 打包

使用 Docker 下载所需的镜像(本步需要使用 Docker,请提前安装),此后在项目根目录下打包:

docker pull quay.io/pypa/manylinux1_x86_64
docker run --rm -v `pwd`:/io quay.io/pypa/manylinux1_x86_64 /io/bin/build-wheel.sh

完成的 Wheel 包位于项目根目录下的 wheelhouse 目录下。



本文作者:继盛

阅读原文

本文为云栖社区原创内容,未经允许不得转载。

<think>好的,我需要回答用户的问题:MaxCompute中是否支持在CASE WHEN语句中使用UDF。首先,我要理解用户的问题。用户可能在使用MaxCompute编写SQL时,想要在CASE WHEN子句中调用自定义函数(UDF),但不确定是否可行,或者是否有特定的限制。 接下来,我需要查阅相关的资料。根据用户提供的引用内容,特别是引用[1]、[3]、[5]提到了UDF的使用情况。例如,引用[1]中说明UDF是一进一出的函数,引用[3]提到Hive中如何上传UDF的jar包,引用[5]则讨论了UDF执行效率的问题。这些信息可以帮助我确认MaxCompute对UDF的支持情况。 首先,MaxCompute支持UDF,包括UDF、UDAF和UDTF。根据引用[1],UDF是用户自定义函数,一进一出,适用于标量处理。而CASE WHEN语句通常用于条件判断,每个分支返回一个标量值,因此可能需要使用标量UDF。 然后,我需要确认在CASE WHEN中是否可以调用UDF。根据一般SQL的语法,CASE WHEN的条件表达式或结果表达式都可以使用函数,包括内置函数和UDF。例如,在WHEN子句中使用UDF判断条件,或者在THEN子句中使用UDF处理返回值。MaxCompute的文档或引用资料是否支持这一点? 查看引用[2],提到MaxCompute的SCRIPTING语法差异,虽然主要讨论变量和流程控制,但可以推测其函数调用机制与标准SQL类似。引用[5]提到UDF执行效率低的问题,但并未禁止使用,反而说明在需要时可以调用,但要注意优化。 因此,可以推断MaxCompute允许在CASE WHEN中使用UDF。不过需要注意UDF的类型必须是标量函数(UDF),因为UDAF和UDTF可能不符合上下文的要求。此外,UDF需要正确注册到MaxCompute项目中,确保在SQL中被正确调用。 接下来,需要给出示例。例如,在CASE WHEN的条件中使用UDF判断,或者在结果中使用UDF处理数据。比如: SELECT CASE WHEN my_udf(column) > 10 THEN 'High' ELSE 'Low' END AS level FROM table; 这样的语法在MaxCompute中应该是支持的,前提是my_udf已经正确注册。 同时,需要注意UDF的数据类型匹配,确保输入参数和返回值与上下文兼容。例如,如果UDF返回的是布尔值,可能适用于WHEN子句的条件判断;如果返回的是字符串或数值,适用于THEN或ELSE后的结果。 总结:MaxCompute支持在CASE WHEN语句中使用UDF,但需确保UDF为标量函数且正确注册,同时注意数据类型的匹配和执行效率的问题。需要提醒用户参考官方文档进行UDF的注册和使用,避免因配置错误导致的问题。</think>MaxCompute 支持在 `CASE WHEN` 语句中使用用户自定义函数(UDF),但需遵循以下规则: --- ### **1. 支持场景** - **标量 UDF**(一进一出)可以直接嵌入 `CASE WHEN` 的条件表达式或结果表达式中,例如: ```sql SELECT CASE WHEN udf_is_valid(name) THEN 'Valid' -- 在条件中使用UDF ELSE udf_default_status() -- 在结果中使用UDF END AS status FROM table; ``` - **UDAF(聚合函数)和 UDTF(表生成函数)** 无法直接在 `CASE WHEN` 中使用,需通过子查询或 `JOIN` 预处理[^1]。 --- ### **2. 使用限制** - **UDF 注册**:需提前将 UDF 的 JAR 包注册到 MaxCompute 项目,并通过 `CREATE FUNCTION` 声明函数名和类路径[^3]。 - **类型匹配**:UDF 的输入/输出类型需与 `CASE WHEN` 上下文兼容。例如,若 `CASE` 要求返回字符串,UDF 的输出类型也应为字符串。 - **性能优化**:若 UDF 逻辑复杂或数据量大,可能引发性能问题,建议结合分区裁剪、过滤条件提前执行等优化手段[^4][^5]。 --- ### **3. 示例** 假设已注册 UDF `udf_parse_category`,用于解析分类: ```sql SELECT id, CASE WHEN udf_parse_category(product) = 'Electronics' THEN '高优先级' WHEN udf_parse_category(product) = 'Books' THEN '普通优先级' ELSE '其他' END AS priority FROM sales_table; ``` --- ### **4. 常见问题** - **错误排查**:若 UDF 调用失败,需检查函数是否注册、资源是否上传至 HDFS、权限是否开放(如通过 `kinit` 认证)[^3]。 - **严格模式**:避免因数据膨胀(如误用 UDF 导致笛卡尔积)触发严格模式限制,可检查日志中的 `StdOut` 提示。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值