GET_BLOB_FROM_OSS是 MaxCompute Object Table 场景下的非结构化数据处理函数。可根据 Object Table 中记录的对象 key,生成一个指向 OSS 对象全部或部分内容的Blob值。
使用场景
该函数适合图片、音视频、PDF、模型输入等大对象的延迟读取和 BLOB 表入库场景。
与GET_DATA_FROM_OSS不同,GET_BLOB_FROM_OSS返回的不是已经下载到当前表达式中的二进制内容,而是包含存储位置、字节范围和可选内容类型等信息的BLOB引用。
后续支持:
使用READ BLOB按需读取 BLOB 内容;
将 BLOB 写入支持 BLOB 类型的目标表,供后续任务读取和处理,详情可见Blob数据类型与多模态存储;
使用GET_BLOB_METADATA函数查看内容长度、内容类型和存储类型等元信息;
直接使用 Object Table 伪列 _blob,作为基础调用形式的简写。
使用限制
MaxCompute需要2.0数据类型,详情可见2.0数据类型版本。
MaxCompute项目需要支持Schema功能,详情请参见Schema功能开启。
暂不支持用于MaxQA查询加速。若基于DataWorks的SQL节点执行需添加参数
SET odps.mcqa.disable=true;与SQL语句一并运行。
与相关函数的区别
函数名称 | 返回类型 | 是否直接返回对象内容 | 典型用途 |
BINARY | 是 | 立即在 SQL 中解析或转换较小的对象内容。 | |
BLOB | 否,返回可供后续读取的 BLOB 引用 | 延迟读取、传给支持 BLOB 的函数、写入 BLOB 表。 | |
STRING | 否,返回有有效期的 OSS 签名 URL | 将对象交给 MaxCompute 之外的 HTTP 客户端下载或上传。 |
命令格式
BLOB GET_BLOB_FROM_OSS(
STRING <full_object_table_name>,
STRING <key>
[, BIGINT <offset>]
[, BIGINT <length>]
[, STRING <object_not_found_policy>]
)如果需要同时指定 length,必须先指定 offset。
不同参数组合方式如下:
GET_BLOB_FROM_OSS(table_name, key)
GET_BLOB_FROM_OSS(table_name, key, object_not_found_policy)
GET_BLOB_FROM_OSS(table_name, key, offset, length)
GET_BLOB_FROM_OSS(table_name, key, offset, length, object_not_found_policy)参数说明
参数 | 是否必填 | 数据类型 | 默认值 | 说明 |
full_object_table_name | 是 | STRING | 无 | 开启Schema语法开关后,完整的Object Table定义路径需包括Project和Schema名称,如 如果在建表时选择了RoleARN的认证方式,该参数将协助用户自动生成访问OSS的STS Token。 |
key | 是 | STRING | 无 | 即被访问对象在该Object Table中的名称。详情请参见查看Object Table属性返回结果中的key参数说明。 |
offset | 否 | BIGINT | 0 | 表示读取对象内容的起始位置,取值大于等于0。 |
length | 否 | BIGINT | -1 | 需要读取的字节数。 |
object_not_found_policy | 否 | STRING | OUTPUT_NULL | 表示缓存数据中存在某个对象的key,但在实际的OSS中该对象已不存在时,MaxCompute返回当前函数调用结果的方式。取值如下:
|
返回值说明
返回BLOB类型。
BLOB 中记录当前对象的 OSS 存储引用、有效字节范围、对象大小等信息,而不是把完整对象内容直接作为返回值携带。因此不能使用STRING(GET_BLOB_FROM_OSS(...))读取文本内容。需要先调用 READ_BLOB 得到 BINARY,再转换成字符串。例如:
SET odps.namespace.schema=true;
SELECT CAST(
READ_BLOB(
GET_BLOB_FROM_OSS(
'<project_name>.<schema_name>.ot_demo',
key
)
) AS STRING
) AS object_text
FROM ot_demo
WHERE key = 'example.txt';使用示例
Object Table 只缓存 OSS 对象元信息,不复制对象内容。OSS 对象新增、删除或变更后,应按照表的元数据刷新策略及时刷新;否则可能出现缓存中有 key、但OSS 中对象已不存在的情况。
数据准备
TXT数据
上传如下TXT数据到OSStest_travel.zip。
创建Object Table。
SET odps.namespace.schema=true; CREATE OBJECT TABLE IF NOT EXISTS txt_demo WITH SERDEPROPERTIES ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole') LOCATION 'oss://oss-<region>-internal.aliyuncs.com/<oss_path>/';读取Object Table。
ALTER TABLE txt_demo REFRESH METADATA; SET odps.namespace.schema=true; SELECT COUNT(*) AS ROW_COUNT FROM txt_demo; -- 返回结果如下: +------------+ | row_count | +------------+ | 20 | +------------+
PDF数据
上传如下PDF数据到OSSpdf_demo.zip。
创建Object Table。
SET odps.namespace.schema=true; CREATE OBJECT TABLE IF NOT EXISTS pdf_demo WITH SERDEPROPERTIES ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole') LOCATION 'oss://oss-<region>-internal.aliyuncs.com/<oss_path>/';读取Object Table。
-- 刷新,即图片元信息缓存在MaxCompute中。 ALTER TABLE pdf_demo REFRESH METADATA; SET odps.namespace.schema=true; SELECT COUNT(*) AS ROW_COUNT FROM pdf_demo; -- 返回结果如下: +------------+ | row_count | +------------+ | 10 | +------------+
步骤一:为每个OSS对象生成BLOB
-- 打开数据类型2.0开关
SET odps.sql.type.system.odps2=true;
-- 打开三层语法开关
SET odps.namespace.schema=true;
-- 通过DataWorks的SQL节点执行时需要加:关闭mcqa
SET odps.mcqa.disable=true;
SELECT
key,
GET_BLOB_FROM_OSS(
'<project>.<schema>.txt_demo',
key
) AS object_blob
FROM txt_demo limit 1;
-- 等价于下方语法:
-- 打开数据类型2.0开关
SET odps.sql.type.system.odps2=true;
-- 打开三层语法开关
SET odps.namespace.schema=true;
-- 通过DataWorks的SQL节点执行时需要加:关闭mcqa
SET odps.mcqa.disable=true;
SELECT
key,
GET_BLOB_FROM_OSS(
'<project>.<schema>.txt_demo',
key,
0,
-1,
'OUTPUT_NULL'
) AS object_blob
FROM txt_demo limit 1;
-- 返回结果如下:
+------+-------------+
| key | object_blob |
+------+-------------+
| test_travel01.txt | CAEQAxrgAgEAAAANAAAAAAAAAAEAAAAAAAAADQAAAAAAAABYAAAAXAAAAGQAAABsAAAAWAEAAFgBAABYAQAAWAEAAFgBAABgAQAAYAEAAGABAABgAQAADwEAAAAAAAAAAAAApAAAAAAAAAAAAAAAAAAAAOQAAAAAAAAAcGFuZ3U6Ly9PRFBTLUNOLUJFSUpJTkctSDoxMDI0MC9wcm9kdWN0L2FsaXl1bi9vZHBzL3l5eV90ZXN0X2Rldi8uRnV4aUpvYlRlbXBSb290LzIwMjYwODA0L0FkaG9jU2luay8yMDI2MDgwNDA5MTcyMzg4NWdqZXZsNmtoNXplNS9jb25zb2xlX3F1ZXJ5X3Rhc2tfMTc4NTgzNTA0MzQxNjBfMC8xLy1leHQtLzIwMjYwODA0MDkxNzIzODg1Z2pldmw2a2g1emU1X00xXzBfMF8wMDAwMDBfY2lkMS5ibG9iAQAAAAAAAAAiACoUsPTTV9LIq38UBOcOFkMuEmqWFngyGQoJbnMtZGlyZWN0Egx5eXlfdGVzdF9kZXY6HTIwMjYwODA0MDkxNzIzODg1Z2pldmw2a2g1emU1 |
+------+-------------+步骤二:使用_blob伪列简写
_blob不是 Object Table 的真实元数据列,因此 SELECT * 不会自动包含该列,必须显式引用。需要设置偏移量、长度、缺失策略或内容类型时,应使用完整函数调用。
-- 打开数据类型2.0开关
SET odps.sql.type.system.odps2=true;
-- 打开三层语法开关
SET odps.namespace.schema=true;
-- 通过DataWorks的SQL节点执行时需要加:关闭mcqa
SET odps.mcqa.disable=true;
SELECT key, _blob FROM txt_demo limit 1;
-- 等价于如下写法
-- 打开数据类型2.0开关
SET odps.sql.type.system.odps2=true;
-- 打开三层语法开关
SET odps.namespace.schema=true;
-- 通过DataWorks的SQL节点执行时需要加:关闭mcqa
SET odps.mcqa.disable=true;
SELECT
key,
GET_BLOB_FROM_OSS(
'<project>.<schema>.txt_demo',
key
) AS `_blob`
FROM txt_demo limit 1;
-- 返回结果如下:
+------+-------+
| key | _blob |
+------+-------+
| test_travel01.txt | CAEQAxreAgEAAAANAAAAAAAAAAEAAAAAAAAADQAAAAAAAABYAAAAXAAAAGQAAABsAAAAVgEAAFYBAABWAQAAVgEAAFYBAABeAQAAXgEAAF4BAABeAQAADwEAAAAAAAAAAAAApAAAAAAAAAAAAAAAAAAAAOIAAAAAAAAAcGFuZ3U6Ly9PRFBTLUNOLUJFSUpJTkctSDoxMDI0MC9wcm9kdWN0L2FsaXl1bi9vZHBzL3l5eV90ZXN0X2Rldi8uRnV4aUpvYlRlbXBSb290LzIwMjYwODA0L0FkaG9jU2luay8yMDI2MDgwNDA5MzAyNzk2NWc4M2FpamkyNjVuL2NvbnNvbGVfcXVlcnlfdGFza18xNzg1ODM1ODI3NDA1MF8wLzEvLWV4dC0vMjAyNjA4MDQwOTMwMjc5NjVnODNhaWppMjY1bl9NMV8wXzBfMDAwMDAwX2NpZDEuYmxvYgEAAAAAAAAAIgAqFA2jSV9PtAiPH3AM0+59uTImxTmQMhkKCW5zLWRpcmVjdBIMeXl5X3Rlc3RfZGV2OhwyMDI2MDgwNDA5MzAyNzk2NWc4M2FpamkyNjVu |
+------+-------+步骤三:读取部分对象内容
以下示例从每个对象的第0字节开始,最多引用64字节。
-- 打开数据类型2.0开关 SET odps.sql.type.system.odps2=true; -- 打开三层语法开关 SET odps.namespace.schema=true; -- 通过DataWorks的SQL节点执行时需要加:关闭mcqa SET odps.mcqa.disable=true; SELECT key, read_blob( GET_BLOB_FROM_OSS( '<project>.<schema>.txt_demo', key, 0, 64 ))AS object_segment FROM txt_demo limit 1; -- 返回结果如下。 +------+----------------+ | key | object_segment | +------+----------------+ | test_travel01.txt | =E5=8C=97=E4=BA=AC=C2=B7=E6=95=85=E5=AE=AB=EF=BC=88=E5=8E=86=E5=8F=B2=E5=8F=A4=E8=BF=B9=EF=BC=89=EF=BC=9A=E7=BA=A2=E5=A2=99=E9=BB=84=E7=93=A6=E9=97=B4=E6=B5=81=E6=B7=8C=E7=9D=80=E5=85=AD=E7=99 | +------+----------------+读取该 BLOB 时,read_blob 看到的是上述字节范围。还可以在该 BLOB 范围内进行二次截取。
SET odps.sql.type.system.odps2=true; -- 打开三层语法开关 SET odps.namespace.schema=true; -- 通过DataWorks的SQL节点执行时需要加:关闭mcqa SET odps.mcqa.disable=true; SELECT read_blob( GET_BLOB_FROM_OSS( '<project>.<schema>.txt_demo', key, 0, 64 ), 0, 32 ) AS first_128_bytes_of_segment FROM txt_demo limit 1; -- 返回结果如下。 +----------------------------+ | first_128_bytes_of_segment | +----------------------------+ | =E5=8C=97=E4=BA=AC=C2=B7=E6=95=85=E5=AE=AB=EF=BC=88=E5=8E=86=E5=8F=B2=E5=8F=A4=E8=BF=B9=EF=BC=89 | +----------------------------+
步骤四:设置内容类型并查看 BLOB 元信息
GET_BLOB_METADATA 函数返回的 JSON 包含 content_type、content_length、storage_type、checksum、content_encoding 等字段。
对于 GET_BLOB_FROM_OSS 生成的值,storage_type 为 OSS;未显式传入 content_type 时,对应元信息为 NULL。
-- 打开数据类型2.0开关
SET odps.sql.type.system.odps2=true;
-- 打开三层语法开关
SET odps.namespace.schema=true;
-- 通过DataWorks的SQL节点执行时需要加:关闭mcqa
SET odps.mcqa.disable=true;
SELECT GET_BLOB_METADATA(
GET_BLOB_FROM_OSS(
'<project>.<schema>.pdf_demo',
key,
'THROW_EXCEPTION',
'application/pdf'
)
) AS blob_metadata
FROM pdf_demo
WHERE key LIKE '%.pdf' limit 1;
-- 返回结果如下:
+---------------+
| blob_metadata |
+---------------+
| {"checksum":null,"content_type":"application/pdf","storage_type":"OSS","is_compressed":false,"content_length":261567,"content_encoding":null,"blob_storage_tier":"STANDARD"} |
+---------------+步骤五:写入 BLOB 表
如果需要长期保存或供后续任务复用,可以将结果写入支持 BLOB 类型的表,详情见Blob数据类型与多模态存储。
-- 打开数据类型2.0开关 SET odps.sql.type.system.odps2=true; -- 打开三层语法开关 SET odps.namespace.schema=true; -- 通过DataWorks的SQL节点执行时需要加:关闭mcqa SET odps.mcqa.disable=true; CREATE TABLE IF NOT EXISTS object_blob_sink ( object_key STRING, object_data BLOB ) TBLPROPERTIES ( 'table.format.version' = '2', 'transactional' = 'true' ); INSERT INTO object_blob_sink SELECT key, GET_BLOB_FROM_OSS( 'yyy_test_dev.default.txt_demo', key, 'THROW_EXCEPTION' ) FROM txt_demo;写入后可以使用
read_blob读取内容-- 打开数据类型2.0开关 SET odps.sql.type.system.odps2=true; SELECT object_key, CAST(READ_BLOB(object_data) AS STRING) AS object_text FROM object_blob_sink WHERE object_key = 'test_travel01.txt'; -- 返回结果如下。 +------------+-------------+ | object_key | object_text | +------------+-------------+ | test_travel01.txt | 北京·故宫(历史古迹):红墙黄瓦间流淌着六百年的皇家威严,秋季银杏金黄时漫步其中,最能感受紫禁城的厚重与静美。 | +------------+-------------+
步骤六:仅处理筛选后的对象
Object Table 查询可以先根据元数据过滤,再为命中的对象生成 BLOB。
例如,仅处理 170 Bytes 以内的 PDF。先过滤 Object Table 元数据可以减少 OSS 状态查询和后续内容读取量。
-- 打开数据类型2.0开关
SET odps.sql.type.system.odps2=true;
-- 打开三层语法开关
SET odps.namespace.schema=true;
-- 通过DataWorks的SQL节点执行时需要加:关闭mcqa
SET odps.mcqa.disable=true;
SELECT
key,
GET_BLOB_FROM_OSS(
'<project>.<schema>.txt_demo',
key,
'WARN_AND_NULL',
'application/txt'
) AS document_blob
FROM txt_demo
WHERE key LIKE '%.txt'
AND size <= 170;
-- 返回结果如下:可看出已筛选过。
+------+---------------+
| key | document_blob |
+------+---------------+
| test_travel01.txt | CAEQAxr1AgEAAAANAAAAAAAAAAEAAAAAAAAADQAAAAAAAABYAAAAXAAAAGQAAABsAAAAVgEAAFYBAABWAQAAVgEAAFYBAABeAQAAXgEAAF4BAAB1AQAADwkAAAAAAAAAAAAApAAAAAAAAAAAAAAAAAAAAOIAAAAAAAAAcGFuZ3U6Ly9PRFBTLUNOLUJFSUpJTkctSDoxMDI0MC9wcm9kdWN0L2FsaXl1bi9vZHBzL3l5eV90ZXN0X2Rldi8uRnV4aUpvYlRlbXBSb290LzIwMjYwODA1L0FkaG9jU2luay8yMDI2MDgwNTAyNTIzNjEyMGc3bDd3NzQxa2pnL2NvbnNvbGVfcXVlcnlfdGFza18xNzg1ODk4MzU1NzI5MF8wLzEvLWV4dC0vMjAyNjA4MDUwMjUyMzYxMjBnN2w3dzc0MWtqZ19NMV8wXzBfMDAwMDAwX2NpZDEuYmxvYgEAAAAAAAAADwAAAAAAAABhcHBsaWNhdGlvbi90eHQiACoUqGGDqqv2cyDwow86F8uQa+wWHdQyGQoJbnMtZGlyZWN0Egx5eXlfdGVzdF9kZXY6HDIwMjYwODA1MDI1MjM2MTIwZzdsN3c3NDFramc= |
| test_travel02.txt | CAEQAxr1AgEAAAANAAAAAAAAAAEAAAAAAAAADQAAAAAAAABYAAAAXAAAAGQAAABsAAAAVgEAAFYBAABWAQAAVgEAAFYBAABeAQAAXgEAAF4BAAB1AQAADwkAAAAAAAAAAAAAoQAAAAAAAACkAAAAAAAAAOIAAAAAAAAAcGFuZ3U6Ly9PRFBTLUNOLUJFSUpJTkctSDoxMDI0MC9wcm9kdWN0L2FsaXl1bi9vZHBzL3l5eV90ZXN0X2Rldi8uRnV4aUpvYlRlbXBSb290LzIwMjYwODA1L0FkaG9jU2luay8yMDI2MDgwNTAyNTIzNjEyMGc3bDd3NzQxa2pnL2NvbnNvbGVfcXVlcnlfdGFza18xNzg1ODk4MzU1NzI5MF8wLzEvLWV4dC0vMjAyNjA4MDUwMjUyMzYxMjBnN2w3dzc0MWtqZ19NMV8wXzBfMDAwMDAwX2NpZDEuYmxvYgEAAAAAAAAADwAAAAAAAABhcHBsaWNhdGlvbi90eHQiACoUUhmRcOOiCCBQ0LXOdBulUociULYyGQoJbnMtZGlyZWN0Egx5eXlfdGVzdF9kZXY6HDIwMjYwODA1MDI1MjM2MTIwZzdsN3c3NDFramc= |
| test_travel04.txt | CAEQAxr1AgEAAAANAAAAAAAAAAEAAAAAAAAADQAAAAAAAABYAAAAXAAAAGQAAABsAAAAVgEAAFYBAABWAQAAVgEAAFYBAABeAQAAXgEAAF4BAAB1AQAADwkAAAAAAAAAAAAAoQAAAAAAAABFAQAAAAAAAOIAAAAAAAAAcGFuZ3U6Ly9PRFBTLUNOLUJFSUpJTkctSDoxMDI0MC9wcm9kdWN0L2FsaXl1bi9vZHBzL3l5eV90ZXN0X2Rldi8uRnV4aUpvYlRlbXBSb290LzIwMjYwODA1L0FkaG9jU2luay8yMDI2MDgwNTAyNTIzNjEyMGc3bDd3NzQxa2pnL2NvbnNvbGVfcXVlcnlfdGFza18xNzg1ODk4MzU1NzI5MF8wLzEvLWV4dC0vMjAyNjA4MDUwMjUyMzYxMjBnN2w3dzc0MWtqZ19NMV8wXzBfMDAwMDAwX2NpZDEuYmxvYgEAAAAAAAAADwAAAAAAAABhcHBsaWNhdGlvbi90eHQiACoU69Ba157khgFI/9FvtdoawcOw4UkyGQoJbnMtZGlyZWN0Egx5eXlfdGVzdF9kZXY6HDIwMjYwODA1MDI1MjM2MTIwZzdsN3c3NDFramc= |
| test_travel08.txt | CAEQAxr1AgEAAAANAAAAAAAAAAEAAAAAAAAADQAAAAAAAABYAAAAXAAAAGQAAABsAAAAVgEAAFYBAABWAQAAVgEAAFYBAABeAQAAXgEAAF4BAAB1AQAADwkAAAAAAAAAAAAAqQAAAAAAAADmAQAAAAAAAOIAAAAAAAAAcGFuZ3U6Ly9PRFBTLUNOLUJFSUpJTkctSDoxMDI0MC9wcm9kdWN0L2FsaXl1bi9vZHBzL3l5eV90ZXN0X2Rldi8uRnV4aUpvYlRlbXBSb290LzIwMjYwODA1L0FkaG9jU2luay8yMDI2MDgwNTAyNTIzNjEyMGc3bDd3NzQxa2pnL2NvbnNvbGVfcXVlcnlfdGFza18xNzg1ODk4MzU1NzI5MF8wLzEvLWV4dC0vMjAyNjA4MDUwMjUyMzYxMjBnN2w3dzc0MWtqZ19NMV8wXzBfMDAwMDAwX2NpZDEuYmxvYgEAAAAAAAAADwAAAAAAAABhcHBsaWNhdGlvbi90eHQiACoUEb5KuihKijpGxK0QjStIO4xvGuYyGQoJbnMtZGlyZWN0Egx5eXlfdGVzdF9kZXY6HDIwMjYwODA1MDI1MjM2MTIwZzdsN3c3NDFramc= |
| test_travel11.txt | CAEQAxr1AgEAAAANAAAAAAAAAAEAAAAAAAAADQAAAAAAAABYAAAAXAAAAGQAAABsAAAAVgEAAFYBAABWAQAAVgEAAFYBAABeAQAAXgEAAF4BAAB1AQAADwkAAAAAAAAAAAAApwAAAAAAAACPAgAAAAAAAOIAAAAAAAAAcGFuZ3U6Ly9PRFBTLUNOLUJFSUpJTkctSDoxMDI0MC9wcm9kdWN0L2FsaXl1bi9vZHBzL3l5eV90ZXN0X2Rldi8uRnV4aUpvYlRlbXBSb290LzIwMjYwODA1L0FkaG9jU2luay8yMDI2MDgwNTAyNTIzNjEyMGc3bDd3NzQxa2pnL2NvbnNvbGVfcXVlcnlfdGFza18xNzg1ODk4MzU1NzI5MF8wLzEvLWV4dC0vMjAyNjA4MDUwMjUyMzYxMjBnN2w3dzc0MWtqZ19NMV8wXzBfMDAwMDAwX2NpZDEuYmxvYgEAAAAAAAAADwAAAAAAAABhcHBsaWNhdGlvbi90eHQiACoUuVU6K/SEmU1aRdxjLSRgXhx0j1MyGQoJbnMtZGlyZWN0Egx5eXlfdGVzdF9kZXY6HDIwMjYwODA1MDI1MjM2MTIwZzdsN3c3NDFramc= |
+------+---------------+性能建议
按对象大小切分任务
GET_BLOB_FROM_OSS 属于 Object Table 内容相关函数,可以触发按对象大小进行任务切分,避免仅按元数据行数切分时,大文件集中到少数 Worker 造成长尾。
默认按对象大小切分时,可根据对象分布调整切分单元:
-- 优先级为 KB > MB > GB。通常应根据对象大小分布和单个对象处理耗时调整,不宜为了增加并发盲目设置过小的切分单元。
-- 默认单位配置,单位为 GiB。
SET odps.sql.object.table.split.unit.gb=1;
-- MB 配置优先于 GB 配置。
SET odps.sql.object.table.split.unit.mb=512;
-- KB 配置优先级最高。
SET odps.sql.object.table.split.unit.kb=512;
-- 如需关闭按对象大小切分,可以设置如下参数。关闭后可能产生额外的预处理作业,具体执行计划以 Logview 为准。
SET odps.sql.object.table.split.by.object.size.enabled=false;避免无意中读取全部大对象
如果下游只需要文件头、魔数或小范围内容,应设置
offset和length。优先使用 Object Table 的
key、size、type、last_modified等元数据列过滤对象。GET_BLOB_FROM_OSS本身主要生成引用,但read_blob和写入 BLOB 表可能触发实际对象读取,应按真实 OSS 流量和计算资源评估成本。若大量对象返回
WARN_AND_NULL,应刷新 Object Table 元数据或检查 OSS 数据生命周期,而不是长期依赖逐对象告警。
常见问题
第一个参数为什么必须使用完整表名?
该参数不仅用于标识 Object Table,也用于从任务上下文取得表对应的 OSS 访问配置。建议始终使用 project.schema.object_table三层全名,并确保它与 FROM 中实际扫描的 Object Table 一致。
为什么对象明明在Object Table中,函数仍返回NULL?
Object Table 查询使用缓存元数据。如果对象在最近一次元数据刷新后被删除,默认策略 OUTPUT_NULL会返回 NULL。可以刷新元数据,或临时使用 WARN_AND_NULL、THROW_EXCEPTION 定位不一致数据。
GET_BLOB_FROM_OSS是否等同于下载对象?
不等同。函数会访问 OSS 获取对象状态和大小,但返回的是 BLOB 引用。调用 read_blob、将 BLOB 交给需要内容的函数,或者把它写入需要物化内容的目标表时,才会读取对应对象字节。
可以把 BLOB 当作分区列或主键吗?
不可以。代码中的类型校验禁止 BLOB 作为分区列或主键,也不支持把 BLOB 嵌套在 ARRAY、MAP、STRUCT等复杂类型中。BLOB 应作为普通数据列使用。
应该选GET_BLOB_FROM_OSS还是签名URL?
后续处理仍在 MaxCompute SQL、BLOB 体系内:使用
GET_BLOB_FROM_OSS。需要立即得到对象二进制内容:使用
GET_DATA_FROM_OSS。需要让 ECS、第三方服务或 HTTP 客户端直接访问 OSS:使用
GET_SIGNED_URL_FROM_OSS。签名 URL 有有效期,且受 Bucket Public Access 配置和网络 Endpoint 可达性影响。
查询blob列详情报错“当前访问存在异常”
详细报错
{"serverCostTime":191,"requestId":"068ebe0f2ed96a2aab0998e0770f40ec", "success":false,"errCode":"CP001", "errMsg":"当前访问存在异常,请从数据分析首页开始访问。"}根本原因
DataWorks的SQL节点默认执行MaxQA。
解决方式
通过DataWorks的SQL节点查询ObjectTable时,需要加上
SET odps.mcqa.disable=true;