已获授权的函数

借助已获授权的函数,您可以与特定用户或群组共享查询结果,而无需为这些用户或群组授予底层表访问权限。例如,已获授权的函数可以计算对数据的聚合,也可以查找表值并在计算中使用该值。

默认情况下,如果用户定义的函数 (UDF) 或表函数查询表,则调用该函数的用户必须有权读取表中的数据。或者,您也可以授权该函数访问包含被引用表的数据集。授权函数可以查询数据集中的表,即使调用该函数的用户无法直接查询这些表也是如此。

向函数授权

您可以同时授权 UDF 和表函数。您可以使用 Google Cloud Console、REST API 或 bq 命令行工具为某个函数授权:

控制台

  1. 在 Google Cloud Console 中转到 BigQuery 页面。

    转到 BigQuery

  2. 在导航面板的资源部分中,展开您的项目并选择数据集。

  3. 在详细信息面板中,点击为例程授权

  4. 为例程授权页面的为例程授权部分中,选择要为其授权的函数的项目 ID、数据集 ID 和例程 ID。

  5. 点击添加授权

API

  1. 调用 datasets.get 方法,提取您希望函数访问的数据集。响应正文包含 Dataset 资源的表示法。

  2. 将以下 JSON 对象添加到 Dataset 资源中的 access 数组:

    {
     "routine": {
       "datasetId": "DATASET_NAME",
       "projectId": "PROJECT_ID",
       "routineId": "ROUTINE_NAME"
     }
    }
    

    其中:

    • DATASET_NAME 是包含 UDF 的数据集的名称。
    • PROJECT_ID 是包含 UDF 的项目的 ID。
    • ROUTINE_NAME 是函数的名称。
  3. 使用修改后的 Dataset 表示法调用 dataset.update 方法。

bq

  1. 使用 bq show 命令获取您希望函数访问的数据集的 JSON 表示法。该命令的输出是 Dataset 资源的 JSON 表示法。将结果保存到本地文件。

    bq show --format=prettyjson TARGET_DATASET > dataset.json
    

    TARGET_DATASET 替换为函数有权访问的数据集的名称。

  2. 修改该文件,将以下 JSON 对象添加到 Dataset 资源中的 access 数组:

    {
     "routine": {
       "datasetId": "DATASET_NAME",
       "projectId": "PROJECT_ID",
       "routineId": "ROUTINE_NAME"
     }
    }
    

    其中:

    • DATASET_NAME 是包含函数的数据集的名称。
    • PROJECT_ID 是包含函数的项目的 ID。
    • ROUTINE_NAME 是函数的名称。
  3. 使用 bq update 命令更新数据集。

    bq update --source dataset.json TARGET_DATASET
    

授权函数示例

以下是创建和使用已获授权的 UDF 的端到端示例。

  1. 创建名为 private_datasetpublic_dataset 的两个数据集。如需详细了解如何创建数据集,请参阅创建数据集

  2. 运行以下语句以在 private_dataset 中创建名为 private_table 的表:

    CREATE OR REPLACE TABLE private_dataset.private_table
    AS SELECT key FROM UNNEST(['key1', 'key1','key2','key3']) key;
    
  3. 运行以下语句以在 public_dataset 中创建名为 count_key 的表:UDF 包含一个针对 private_tableSELECT 语句。

    CREATE OR REPLACE FUNCTION public_dataset.count_key(input_key STRING)
    RETURNS INT64
    AS
    ((SELECT COUNT(1) FROM private_dataset.private_table t WHERE t.key = input_key));
    
  4. 向用户授予针对 public_dataset 数据集的 bigquery.dataViewer 角色。此角色包含 bigquery.routines.get 权限,此权限可让用户调用函数。如需了解如何分配对数据集的访问权限控制,请参阅控制对数据集的访问权限

  5. 此时,用户有权调用 count_key 函数,但无法访问 private_dataset 中的表。如果用户尝试调用该函数,则将收到类似于以下内容的错误消息:

    Access Denied: Table myproject:private_dataset.private_table: User does
    not have permission to query table myproject:private_dataset.private_table.
    
  6. 使用 bq 命令行工具运行 show 命令,如下所示:

    bq show --format=prettyjson private_dataset > dataset.json
    

    输出将保存到名为 dataset.json 的本地文件中。

  7. 修改 dataset.json 以将下列 JSON 对象添加到 access 数组中:

    {
     "routine": {
       "datasetId": "public_dataset",
       "projectId": "PROJECT_ID",
       "routineId": "count_key"
     }
    }
    

    PROJECT_ID 替换为 public_dataset 的项目 ID。

  8. 使用 bq 命令行工具运行 update 命令,如下所示:

    bq update --source dataset.json private_dataset
    
  9. 如需验证 UDF 是否有权访问 private_dataset,用户可以运行以下查询:

    SELECT public_dataset.count_key('key1');