使用 ObjectRef 值

本文档介绍了 ObjectRef 值,以及如何在 BigQuery 中创建和使用这些值。

ObjectRef 值是一种 STRUCT 类型 具有预定义架构,用于引用 Cloud Storage 对象以进行 多模态分析。它可以由 OBJ 函数、 AI 函数或 Python 用户定义的函数进行处理。

架构

ObjectRef 值具有以下字段:

名称 Type Mode 说明 示例
uri STRING REQUIRED Cloud Storage 对象的 URI。 "gs://cloud-samples-data/vision/demo-img.jpg"
version STRING NULLABLE 对象生成。 "1560286006357632"
authorizer STRING NULLABLE 用于 委托 访问的 BigQuery 连接 ID,或用于 直接访问的 NULL。 该 ID 可以采用以下格式:
"region.connection"
或
"project.region.connection"
"myproject.us.myconnection"
details JSON NULLABLE 对象元数据或处理对象时出现的错误。它可以包含对象的 content_type、md5_hash、size 和 updated 字段。 {"gcs_metadata":{"content_type":"image/png","md5_hash":"dfbbb5cf034af026d89f2dc16930be15","size":915052,"updated":1560286006000000}}

details 列中 gcs_metadata 字段的 content_type 字段是从 Cloud Storage 中提取的。您可以在 Cloud Storage中设置对象的内容类型。如果您在 Cloud Storage 中省略此字段,BigQuery 会根据 URI 的后缀推断内容类型。

创建 ObjectRef 值

您可以使用 ObjectRef 值,方法是使用 对象表、 OBJ.MAKE_REF 函数或 Cloud Storage Insights 数据集。

使用对象表

如果您没有将 URI 存储在表中,并且想要列出 Cloud Storage 前缀中的所有对象,请使用对象表。对象表会在每一行中存储对对象的引用,并具有包含 ObjectRef 值的 ref 列。以下查询使用 CREATE EXTERNAL TABLE语句 创建对象表:

CREATE EXTERNAL TABLE mydataset.images
WITH CONNECTION `us.myconnection`
OPTIONS (uris=["gs://mybucket/images/*"], object_metadata="SIMPLE");

SELECT ref AS image_ref FROM mydataset.images;

ObjectRef 对象表中的值必须具有用于 委托访问的授权方。授权方连接与您用于创建对象表的连接相同。

使用 OBJ.MAKE_REF 函数

如果您已将 URI 存储在表中,并且想要根据这些 URI 创建 ObjectRef 值,请使用 OBJ.MAKE_REF 函数。以下查询展示了如何根据包含 Cloud Storage URI 的 uri 列在 image_ref 列中创建 ObjectRef 值:

-- Specify only the URI
SELECT *, OBJ.MAKE_REF(uri) AS image_ref FROM mydataset.images;
-- Specify the URI and the connection
SELECT *, OBJ.MAKE_REF(uri, "us.myconnection") AS image_ref FROM mydataset.images;

如需修改现有 ObjectRef 值的授权方,您可以使用 OBJ.MAKE_REF 函数:

-- Remove the authorizer
SELECT *, OBJ.MAKE_REF(ref, authorizer=>NULL) AS image_ref FROM mydataset.images;
-- Change the authorizer
SELECT *, OBJ.MAKE_REF(ref, authorizer=>"us.myconnection2") AS image_ref FROM mydataset.images;

OBJ.MAKE_REF 函数接受可为 null 的授权方,以支持 直接访问和委托访问。

使用 Cloud Storage Insights 数据集

如果您已配置 Storage Insights 数据集, 则该数据集已包含一个包含 ObjectRef 值的 ref 列 。在 Storage Insights 数据集中创建的任何 ObjectRef 值都没有授权方。如需查询这些对象,您必须 直接访问该对象,或者向 ObjectRef 添加授权方以使用委托访问。

授权方和权限

当您将 ObjectRef 值传递给 ObjectRef 函数、AI 函数或 Python UDF 时,这些函数需要访问存储在 Cloud Storage 中的对象。您可以根据 authorizer 字段的值,通过以下两种方式授权此访问:直接访问和委托访问。

直接访问

通过 直接访问,运行查询的用户可以使用自己的凭据直接访问对象 。当 ObjectRef 值没有授权方时,系统会使用直接访问。

直接访问具有以下限制:

  • 用户必须有权访问对象。
  • 使用 AI.GENERATE、 AI.IF、 AI.SCORE或 AI.CLASSIFY 函数且没有连接的查询作业需要用户具有 额外的权限。 查询只能访问执行作业的同一项目中的 Cloud Storage 存储分区和对象。

例如,如果您对没有授权方的 ObjectRef 值调用 AI.GENERATE 函数,则该函数会以您的身份读取对象。如果您 没有读取对象的权限,该函数会在结果的 status 列中写入 "permission denied" 错误。

以下示例展示了一个使用直接访问的查询:

-- Requires that the end user can read the object "gs://cloud-samples-data/vision/demo-img.jpg" and use the Agent Platform model.
SELECT AI.GENERATE(
  ("Describe this image:",
  OBJ.MAKE_REF("gs://cloud-samples-data/vision/demo-img.jpg")));

委托访问

通过 委托访问,运行查询的用户会将对象访问权限委托给 BigQuery Cloud 资源连接,该连接在 authorizer 值的 ObjectRef 字段中指定。委托访问可以实现跨项目数据访问权限。

如需使用委托访问,您的数据管理员必须按照以下步骤设置连接和权限:

例如,如果用户将具有授权方的 ObjectRef 值传递给 AI.GENERATE 函数,则该函数会验证用户是否具有 bigquery.objectRefs.read 权限,然后使用连接的服务帐号读取对象。如果用户或服务帐号 权限不足,该函数会在结果的 status 列中写入 "permission denied" 错误 。

以下示例展示了一个使用委托访问的查询。它需要满足以下条件:

  • 用户对 connection1 具有 bigquery.objectRefs.read 权限。
  • connection1 的服务帐号对该对象具有 storage.objects.get 权限。
  • connection2 的服务帐号具有 Agent Platform User 角色。
SELECT AI.GENERATE(
  ("Describe this image:",
    OBJ.MAKE_REF("gs://cloud-samples-data/vision/demo-img.jpg", "us.connection1")),
  connection_id => "us.connection2");

在 VPC Service Controls 边界内,AI 函数 无法处理 ObjectRef 值,这些值使用委托访问。委托访问会为对象生成已签名的 HTTPS 网址,而 Gemini Enterprise Agent Platform 会阻止对边界内项目的 HTTP 和 HTTPS 提取。该函数会在结果的 status 列中写入以下错误:

INVALID_ARGUMENT: HTTP links are not supported for requests restricted by VPCSC.

由于 对象表的 ref 列始终使用对象 表的连接作为授权方,因此在 边界内将 ref 传递给 AI 函数始终会返回此错误。如需分析对象,请改为传递单参数 OBJ.MAKE_REF(uri)值,该值使用 直接访问并将 Cloud Storage URI 发送到 模型,而无需生成签名网址。

最佳实践

在决定是使用直接访问还是委托访问时,请考虑以下最佳实践:

  • 对于在单个项目中进行数据存储和分析的小型团队,请使用 直接访问 。数据管理员使用 Identity and Access Management 授予用户对 BigQuery 数据和 Cloud Storage 数据的访问权限。用户可以根据需要创建没有授权方的 ObjectRef 值,以使用自己的凭据分析对象。
  • 对于跨多个项目运行的大型团队,尤其是在数据存储和分析分离的情况下,请使用 委托访问 。数据管理员可以提前设置连接并创建 ObjectRef 值以进行分析,并将连接作为其授权方。此方法适用于对象表,或通过对 URI 列表使用 OBJ.MAKE_REF 来实现。 然后,数据管理员可以将存储 ObjectRef 值的表与分析师共享。分析师无需访问原始存储桶即可分析对象。

错误

使用 ObjectRef 值的函数会通过以下两种方式报告错误:

  • 查询失败:查询可能会失败,并显示错误消息,且没有结果。
  • 返回错误值:查询成功,但函数可能会将错误作为返回值的一部分写入。如需了解返回值格式,请参阅您所用函数的参考页面。

当函数返回 ObjectRef 值时,该值的 details 字段可能包含 errors 字段。如果包含,则该字段的值是一个错误数组。每个错误都具有以下架构:

名称 Type Mode 说明 示例
code INT64 REQUIRED 标准 HTTP 错误代码。 400
message STRING REQUIRED 描述性强且用户友好的错误消息。 "Connection credential for myproject.us.nonexistent_connection cannot be used. Either the connection does not exist, or the user does not have sufficient permissions (bigquery.objectRefs.read)"
source STRING REQUIRED 触发错误的函数的名称。 "OBJ.MAKE_REF"

以下是两种常见的错误类型:

  • 对象错误:提供的对象 URI 或版本不存在。
  • 授权方错误:连接不存在,或者用户没有 使用该连接进行委托访问的权限。

以下查询展示了如何从 Objectref 列中选择包含错误的 ObjectRef 值:

SELECT ref
FROM mydataset.images
WHERE ref.details.errors IS NOT NULL;

后续步骤