使用 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 Vertex AI model.
SELECT AI.GENERATE(
("Describe this image:",
OBJ.MAKE_REF("gs://cloud-samples-data/vision/demo-img.jpg")),
endpoint => 'gemini-2.5-pro');
委托访问
通过 委托访问,运行查询的用户会将对象访问权限委托给 BigQuery Cloud 资源连接,该连接在 authorizer 值的 ObjectRef 字段中指定。委托访问可以实现跨项目数据访问权限。
如需使用委托访问,您的数据管理员必须按照以下步骤设置连接和权限:
- 一次性设置 。数据管理员必须
设置 Cloud 资源连接
来管理 Cloud Storage 存储桶:
- 创建新的 BigQuery Cloud 资源连接,或重复使用项目中的现有连接。
- 在连接的元数据中查找服务帐号。
- 在项目或
Cloud Storage 存储分区中,为服务帐号授予读取的
storage.objects.get权限,或写入的storage.objects.create权限。您可以使用 Storage Object Viewer 或 Storage Object User 角色授予这些权限。
- 按用户设置 。数据管理员必须为用户授予读取的
bigquery.objectRefs.read权限,或写入的bigquery.objectRefs.write权限,以连接到 BigQuery。您可以使用 以下角色授予这些权限: BigQuery ObjectRef Reader 或 BigQuery ObjectRef Admin 。
例如,如果用户将具有授权方的 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")),
endpoint => 'gemini-2.5-pro',
connection_id => "us.connection2");
最佳做法
在决定是使用直接访问还是委托访问时,请考虑以下最佳实践:
- 对于在单个项目中进行数据存储和分析的小型团队,请使用 直接访问 。数据管理员使用 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;
后续步骤
- 在表架构中指定
ObjectRef列。 - 分析多模态数据。
- 详细了解 ObjectRef 函数。