本文介紹通過Object Table產生簽名地址以實現OSS對象的上傳和下載。
背景資訊
MaxCompute的Object Table可用來處理OSS上非結構化資料,Object Table和SQL計算可以協助使用者精準篩選待處理的圖片列表(如跟進時間、名稱、大小等),並將其傳遞給第三方服務進行處理。然而,這些計算服務在下載OSS對象時需要具備相應的許可權,通常的方式是通過永久AK/SK或服務角色扮演,但這些方式存在一定的弊端:
永久AK/SK涉及安全隱患,使用者需將AK/SK儲存於第三方服務中,一旦泄露,將面臨較高的風險。
服務扮演角色通常指的是MaxCompute在訪問OSS時所扮演的角色,而第三方則需要單獨扮演其他角色,增加了代碼的複雜性。
目前OSS支援使用預簽名URL下載或預覽檔案。只要該URL在簽名時的有效期間足夠長,使用者即可通過HTTP協議直接存取,操作非常簡便。除了可以產生用於下載的URL外,還可以產生用於上傳資料的URL,使用者可根據需求自行選擇其用途。
GET_SIGNED_URL_FROM_OSS
產生用於下載或上傳OSS資料的免密簽名URL,使使用者通過HTTP協議直接讀寫OSS檔案。
使用限制
目前僅支援通過OSS內網方式建立Object Table。
暫不支援用於MaxQA查詢加速。需添加參數
SET odps.mcqa.disable=true;與SQL語句一併運行。如果OSS Bucket啟用了阻止公用訪問功能,則無法通過
GET_SIGNED_URL_FROM_OSS函數產生公網可訪問的簽名地址。請確保Bucket許可權配置允許產生和使用簽名地址。
函數定義
STRING GET_SIGNED_URL_FROM_OSS (
STRING <full_object_table_name>,
STRING <key>
[, INT <timeToLiveSeconds>]
[, DATETIME <expiration>]
[, STRING <httpMethod>]
)參數說明
參數 | 是否必填 | 資料類型 | 說明 | 預設值 |
full_object_table_name | 是 | STRING | 三層模型下,完整的OBJECT TABLE路徑,包括Project和Schema名稱,如 如果在建表時選擇了RoleARN的認證方式,該參數將協助使用者自動產生訪問OSS的STS Token。 | 無 |
key | 是 | STRING | 即被訪問對象在該Object Table中的名稱。詳情請參見查看OBJECT TABLE屬性返回結果中的key參數說明。 | 無 |
timeToLiveSeconds | 否 | INT | 簽名URL的有效期間時間長度,最小1秒,最大7天(604800秒)。與expiration不可同時使用。 | 預設為3600秒。 |
expiration | 否 | DATETIME | 簽名URL到期時間點。最小比目前時間大1秒,最大比目前時間多7天(604800秒)。 與timeToLiveSeconds不可同時使用。 | 預設比目前時間大3600秒。 |
httpMethod | 否 | STRING | 產生URL之後使用方式,是下載(讀取OSS資料)還是上傳(資料寫入OSS)。
| 預設值是GET。 |
傳回值說明
返回STRING類型,產生的預簽名URL。
其他情境函數定義
最精簡模式,3600秒到期時間長度,預設GET。
STRING get_signed_url_from_oss ( STRING <fullTableName>, STRING <ossKey> );自訂到期時間長度,預設GET。
STRING GET_SIGNED_URL_FROM_OSS( STRING <fullTableName>, STRING <ossKey>, INT <timeToLiveSeconds> );自訂到期時間長度以及讀寫用途。
STRING GET_SIGNED_URL_FROM_OSS( STRING <fullTableName>, STRING <ossKey>, INT <timeToLiveSeconds>, STRING <httpMethod> );自訂到期時間點,預設GET。
STRING GET_SIGNED_URL_FROM_OSS( STRING <fullTableName>, STRING <ossKey>, DATETIME <expiration> );自訂到期時間點以及讀寫用途。
STRING GET_SIGNED_URL_FROM_OSS( STRING <fullTableName>, STRING <ossKey>, DATETIME <expiration>, STRING <httpMethod> );
使用樣本
此處以杭州地區為例,展示如何在ECS中通過產生預簽名URL下載OSS對象。
執行下述代碼時,需要將project_name和schema_name替換成實際的專案名稱和Schema名稱。
在ECS通過產生預簽名URL下載OSS對象
步驟一:產生下載OSS對象的URL
登入OSS控制台,上傳測試資料signedget.txt至
object-table-test/object_table_folder目錄下。具體操作請參見上傳檔案。使用本地用戶端(odpscmd),或在DataWorks中建立MaxCompute SQL節點,以建立Object Table並重新整理中繼資料資訊緩衝。
-- Object Table在MaxCompute專案中支援Schema功能,開啟三層模型。 SET odps.namespace.schema=true; -- 選擇對應MaxCompute專案。 USE <project_name>; -- 選擇對應的schema。 USE SCHEMA <schema_name>; -- Object Table在MaxCompute專案中支援2.0資料類型系統。 SET odps.sql.type.system.odps2=true; -- 目前在MaxQA查詢加速中暫不支援使用。 SET odps.mcqa.disable=true; -- 建立Object Table。 CREATE OBJECT TABLE IF NOT EXISTS test_get_signed_url_from_oss LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/object-table-test/object_table_folder/'; -- 重新整理表緩衝。 ALTER TABLE test_get_signed_url_from_oss REFRESH METADATA;查詢Object Table表中的中繼資料資訊。
SELECT * FROM test_get_signed_url_from_oss;返回結果如下:
+---------------+------------+------------+---------------------+---------------+----------------------------------+--------------+------------+--------------------+ | key | size | type | last_modified | storage_class | etag | restore_info | owner_id | owner_display_name | +---------------+------------+------------+---------------------+---------------+----------------------------------+--------------+------------+--------------------+ | signedget.txt | 38 | Normal | 2025-06-04 01:36:52 | Standard | 96D8258845DAB51BC9B****6E61A2563 | NONE | 13**** | 13**** | +---------------+------------+------------+---------------------+---------------+----------------------------------+--------------+------------+--------------------+通過函數GET_DATA_FROM_OSS讀取對象資料。
SELECT STRING( GET_DATA_FROM_OSS( '<project_name>.<schema_name>.test_get_signed_url_from_oss', key ) ) FROM test_get_signed_url_from_oss;返回結果如下:
+----------------------------------------+ | _c0 | +----------------------------------------+ | test maxcompute download files by url | +----------------------------------------+查詢Object Table並產生簽名地址URL。
SELECT GET_SIGNED_URL_FROM_OSS( '<project_name>.<schema_name>.test_get_signed_url_from_oss', key) FROM test_get_signed_url_from_oss;返回結果如下:
+------------+ | _c0 | +------------+ | http://object-table-test.oss-cn-hangzhou-internal.aliyuncs.com/object_table_folder%2Fsignedget.txt?Expires=17490****&OSSAccessKeyId=STS.****&Signature=****&security-token=**** | +------------+
步驟二:通過ECS伺服器下載
登入ECS控制台,單擊左側導覽列。
切換杭州地區,選擇目標執行個體,單擊遠端連線,通過Workbench串連ECS執行個體。
在終端對話方塊執行如下指令,下載OSS對象:
-- 切換至opt目錄下 cd /opt --通過簽名URL下載對應OSS對象。 curl -o /opt/ecs_signed.txt "http://object-table-test.oss-cn-hangzhou-internal.aliyuncs.com/object_table_folder%2Fsignedget.txt?Expires=17490****&OSSAccessKeyId=STS.****&Signature=****&security-token=****"返回結果如圖所示:

在ECS通過產生預簽名URL上傳OSS對象
步驟一:產生上傳OSS對象的URL
使用已建立的Object Table表test_get_signed_url_from_oss。查詢Object Table並產生簽名地址URL。代碼如下所示:
SELECT get_signed_url_from_oss(
'<project_name>.<schema_name>.test_get_signed_url_from_oss',
key,
3600,
'PUT'
)
FROM test_get_signed_url_from_oss;返回結果如下:
+------------+
| _c0 |
+------------+
| http://object-table-test.oss-cn-hangzhou-internal.aliyuncs.com/object_table_folder%2Fsinged_put?Expires=17490****&OSSAccessKeyId=****&Signature=****&security-token=**** |
+------------+步驟二:通過ECS伺服器上傳
使用已建立的ECS伺服器,準備測試資料signedput.txt,並上傳至opt目錄下。
在Workbench終端執行如下指令,上傳資料至OSS。
-- 切換至opt目錄下 cd /opt --通過簽名URL上傳signedput.txt至OSS。 curl -X PUT -T /opt/signedput.txt -i "http://object-table-test.oss-cn-hangzhou-internal.aliyuncs.com/object_table_folder%2Fsinged_put?Expires=17490****&OSSAccessKeyId=****&Signature=****&security-token=****"返回結果如圖所示:

步驟三:查詢Object Table中繼資料資訊
重新整理表緩衝,指令如下:
ALTER TABLE test_get_signed_url_from_oss REFRESH METADATA;查詢Object Table表中的中繼資料資訊,指令如下:
SELECT * FROM test_get_signed_url_from_oss;返回結果如下:
+------------+------------+------------+---------------+---------------+------------+--------------+------------+--------------------+ | key | size | type | last_modified | storage_class | etag | restore_info | owner_id | owner_display_name | +------------+------------+------------+---------------+---------------+------------+--------------+------------+--------------------+ | signedget.txt | 38 | Normal | 2025-06-03 01:36:52 | Standard | 96D8258845DAB51BC****546E61A2563 | NONE | 13**** | 13**** | | singed_put | 44 | Normal | 2025-06-03 19:31:23 | Standard | F5EA64DF895CF08C3****7D3FD09F12 | NONE | 13**** | 13**** | +------------+------------+------------+---------------+---------------+------------+--------------+------------+--------------------+通過GET_DATA_FROM_OSS,讀取OSS對象資料。指令如下:
SELECT string( get_data_from_oss( '<project_name>.<schema_name>.test_get_signed_url_from_oss', key ) ) FROM test_get_signed_url_from_oss;返回結果如下:
+------------+ | _c0 | +------------+ | test maxcompute download files by url | | test Object Table upload file to oss by url | +------------+
常見問題
問題1:函數中的表路徑和底層被查詢的表路徑不同
報錯資訊
ODPS-0130071:[0,0] Semantic analysis exception - physical plan generation failed: Can't do ObjectTableTwoPhasesSplitting process (Caused by: java.lang.IllegalArgumentException: The first arg[xxx.default.test_get_signed_url_from_ossxxxxxx] of function GET_SIGNED_URL_FROM_OSS({object_table_full_name}, {object_key}, ...) can't be found in the underlying object table scans[xxx.default.test_get_signed_url_from_oss])。錯誤描述
test_get_signed_url_from_ossxxxxxx該表名不存在或者與SQL中被訪問的表名不同。解決方案
寫入真實存在且相同的Object Table表名,且用
project.schema.table格式。
問題2:timeToLiveSeconds參數值不正確
報錯資訊
ODPS-0121095:[1,8] Invalid argument - The parameter <timeToLiveSeconds> of the function GET_SIGNED_URL_FROM_OSS() you specified (0) is invalid, it should be in the range [1, 604800]。錯誤描述
函數中的到期時間長度(timeToLiveSeconds)參數值不正確,必須在[1, 604800]之間。
解決方案
需寫入正確範圍內的到期時間長度。
問題3: HttpMethod參數值不正確
報錯資訊
ODPS-0121095:[1,8] Invalid argument - The parameter <httpMethod> of the function GET_SIGNED_URL_FROM_OSS() you specified 'PU' is invalid, it can only be 'GET' or 'PUT'。錯誤描述
函數中的HttpMethod參數值不正確。
解決方案
HttpMethod參數值只能為GET或者PUT。
問題4:簽章時間太短,連結已逾時
報錯資訊
執行curl命令報錯Request has expired。
錯誤描述
簽名URL時間太短,訪問時已經到期。
解決方案
expiration參數值需要設定的合理一些,過長或過短都不建議。
問題5:未開啟三層模型文法開關
報錯資訊
ODPS-0130071:[0,0] Semantic analysis exception - physical plan generation failed: Can't do ObjectTableTwoPhasesSplitting process (Caused by: java.lang.IllegalArgumentException: Invalid parameter of object table full name[str=xxx.test_get_signed_url_from_oss], which should be split up into 3 parts by '.' like '${project}.${schema}.${table}')。錯誤描述
未開啟Schema文法開關,無法識別
project.schema.table文法格式。解決方案
函數SQL前需加上
set odps.namespace.schema=true;開啟Schema文法開關。