全部產品
Search
文件中心

MaxCompute:產生簽名地址上傳和下載OSS對象

更新時間:Sep 23, 2025

本文介紹通過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名稱,如project.schema.object_table

如果在建表時選擇了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表示下載。

  • PUT表示上傳。

預設值是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_nameschema_name替換成實際的專案名稱和Schema名稱。

在ECS通過產生預簽名URL下載OSS對象

步驟一:產生下載OSS對象的URL

  1. 登入OSS控制台,上傳測試資料signedget.txtobject-table-test/object_table_folder目錄下。具體操作請參見上傳檔案

  2. 使用本地用戶端(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;
  3. 查詢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****             |
    +---------------+------------+------------+---------------------+---------------+----------------------------------+--------------+------------+--------------------+
  4. 通過函數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  |
    +----------------------------------------+
  5. 查詢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伺服器下載

  1. 登入ECS控制台,單擊左側導覽列執行個體與鏡像 > 執行個體

  2. 切換杭州地區,選擇目標執行個體,單擊遠端連線,通過Workbench串連ECS執行個體。

  3. 在終端對話方塊執行如下指令,下載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=****"

    返回結果如圖所示:

    yuddd

在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伺服器上傳

  1. 使用已建立的ECS伺服器,準備測試資料signedput.txt,並上傳至opt目錄下。

  2. 在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=****"

    返回結果如圖所示:

    opopopo

步驟三:查詢Object Table中繼資料資訊

  1. 重新整理表緩衝,指令如下:

    ALTER TABLE test_get_signed_url_from_oss REFRESH METADATA;
  2. 查詢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****   |
    +------------+------------+------------+---------------+---------------+------------+--------------+------------+--------------------+
  3. 通過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文法開關。