bigquery-udfs
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseBigQuery User-Defined Functions (UDFs)
BigQuery 用户自定义函数(UDF)
BigQuery User-Defined Functions (UDFs) extend GoogleSQL with custom logic
written in SQL, JavaScript, managed Python (), or hosted externally
as Remote Functions on Cloud Run and Cloud Run functions.
python-3.11BigQuery 用户自定义函数(UDF)通过以 SQL、JavaScript、托管 Python()编写的自定义逻辑扩展 GoogleSQL,也可以作为 Remote Function 部署在 Cloud Run 和 Cloud Run functions 上。
python-3.11Attribution
归因
Tag every BigQuery or Google Cloud command you execute directly in the terminal
while using this skill, so usage can be attributed. The tag identifies only the
skill and its version; it carries no user data.
-
Prefix everyinvocation, whatever the subcommand, with the metrics environment variables. Set them inline on each command; shell state may not persist between commands:
gcloudbashCLOUDSDK_METRICS_REQUEST_ATTRIBUTION="agent-skills/1.0 (skill:bigquery-udfs)" \ gcloud <command> [flags]Do not usefor this: it would persist beyond the current task and mislabel unrelated usage.gcloud config set -
On direct HTTP calls to the BigQuery APIs (for example with) or HTTP requests to the MCP server, append this exact string to the end of the existing User-Agent header — the collection pipeline parses the
curlandagent-skills/<version>tokens, so any rewording breaks attribution:skill:<name>User-Agent: <existing_user_agent> agent-skills/1.0 (skill:bigquery-udfs) -
Constraint for Generated Code: The tracking prefix is strictly for commands you execute directly in the terminal. Do NOT include this tracking prefix in generated SQL, scripts, Terraform templates, or code provided to the user for their own repositories.
使用此 skill 时,对于在终端中直接执行的每一条 BigQuery 或 Google Cloud 命令,都要添加标签,以便归因其使用情况。该标签仅标识 skill 及其版本,不包含用户数据。
-
对每一次调用,无论使用何种子命令,都要在命令前加上指标环境变量。由于 shell 状态可能无法在命令之间保留,请将它们内联设置在每条命令上:
gcloudbashCLOUDSDK_METRICS_REQUEST_ATTRIBUTION="agent-skills/1.0 (skill:bigquery-udfs)" \ gcloud <command> [flags] -
对 BigQuery API 的直接 HTTP 调用(例如使用)或对 MCP 服务器发出的 HTTP 请求,应将以下确切字符串追加到现有 User-Agent 请求头的末尾——收集管道会解析
curl和agent-skills/<version>标记,因此任何改写都会破坏归因:skill:<name>User-Agent: <existing_user_agent> agent-skills/1.0 (skill:bigquery-udfs) -
生成代码的约束:跟踪前缀严格用于直接在终端执行的命令。不要将此跟踪前缀包含在提供给用户、供其自有仓库使用的生成 SQL、脚本、Terraform 模板或代码中。
Choosing the Right UDF Type
选择合适的 UDF 类型
Always select the lightest-weight runtime that satisfies the requirement,
because BigQuery optimizes native SQL expressions inline while external runtimes
incur serialization and container startup overhead:
| UDF Type | Connection Required? | When to Use | Key Constraints |
|---|---|---|---|
| SQL UDF (Default) | No | Composable expressions, regex, struct/array manipulation, aggregate functions ( | Lowest latency; zero external dependencies; supports |
| JavaScript UDF | No | Custom string/JSON logic or bundling | Runs in V8 sandbox; |
| Managed Python UDF (Offline) | No | Pure compute using Python 3.11, PyPI wheels ( | Persistent functions only ( |
Managed Python UDF ( | Yes ( | Invoking Google Cloud APIs (e.g., Cloud Translation, Gemini Enterprise Agent Platform) or online HTTP endpoints directly from Python inside BigQuery containers. | Requires |
Remote Function ( | Yes ( | Calling external APIs or microservices when you need non-Python runtimes (Go, Java, Node.js), private VPC network access, GPUs, or custom Cloud Run scaling. | Requires Cloud Run HTTPS endpoint implementing BigQuery JSON batch contract and |
始终选择能够满足需求的运行时中开销最低的一种,因为 BigQuery 会将原生 SQL 表达式内联优化,而外部运行时会产生序列化和容器启动开销:
| UDF 类型 | 是否需要 Connection? | 使用场景 | 关键限制 |
|---|---|---|---|
| SQL UDF(默认) | 否 | 可组合表达式、正则表达式、struct/array 操作、聚合函数( | 延迟最低;无外部依赖;支持 |
| JavaScript UDF | 否 | 自定义字符串/JSON 逻辑,或从 Cloud Storage( | 在 V8 sandbox 中运行;不支持 |
| 托管 Python UDF(Offline) | 否 | 使用 Python 3.11 进行纯计算,支持 PyPI wheels( | 仅支持持久化函数(不支持 |
托管 Python UDF( | 是( | 从 BigQuery 容器内的 Python 直接调用 Google Cloud API(例如 Cloud Translation、Gemini Enterprise Agent Platform)或在线 HTTP 端点。 | 需要 |
Remote Function( | 是( | 调用外部 API 或微服务,适用于需要非 Python 运行时(Go、Java、Node.js)、私有 VPC 网络访问、GPU 或自定义 Cloud Run 扩缩容的场景。 | 需要一个实现 BigQuery JSON 批处理契约的 Cloud Run HTTPS 端点,并需要 |
Prerequisites & Setup
前提条件与设置
Ensure the Google Cloud project has an active billing account attached (see
BigQuery Pricing):
-
Install and Authenticate Google Cloud SDK: Install the Google Cloud SDK and authenticate:bash
gcloud auth loginPassand--project={project_id}(or--region={region}for--location) explicitly on each command instead of runningbq, which persists beyond the task. Default togcloud config setwhen the user has not specified a region (see BigQuery Locations).us-central1 -
Enable Required APIs:
- For SQL, JavaScript, and offline Python UDFs:
bigquery.googleapis.com - Additionally for Python UDFs calling APIs () and Remote Functions:
WITH CONNECTION(andbigqueryconnection.googleapis.comfor Remote Functions)run.googleapis.com
bashCLOUDSDK_METRICS_REQUEST_ATTRIBUTION="agent-skills/1.0 (skill:bigquery-udfs)" \ gcloud services enable bigquery.googleapis.com \ bigqueryconnection.googleapis.com \ run.googleapis.com --quiet - For SQL, JavaScript, and offline Python UDFs:
-
Verify Required IAM Roles:
- All UDFs: on the dataset and
roles/bigquery.dataEditoron the project.roles/bigquery.jobUser - When using (API-calling Python UDFs & Remote Functions):
WITH CONNECTION- UDF Creator: on the project (plus
roles/bigquery.connectionAdmin, e.g.,resourcemanager.projects.setIamPolicy, when granting project-level IAM roles to the connection service account viaroles/resourcemanager.projectIamAdmin).GRANT ... ON PROJECT - UDF Caller: on the connection.
roles/bigquery.connectionUser
- UDF Creator:
- All UDFs:
确保 Google Cloud 项目已关联有效的结算账号(请参阅 BigQuery Pricing):
-
安装并认证 Google Cloud SDK:安装 Google Cloud SDK 并完成认证:bash
gcloud auth login每条命令都显式传入和--project={project_id}(对于--region={region}使用bq),不要运行--location,因为该设置会持续到当前任务之外。如果用户未指定区域,默认使用gcloud config set(请参阅 BigQuery Locations)。us-central1 -
启用所需 API:
- 对于 SQL、JavaScript 和 Offline Python UDF:
bigquery.googleapis.com - 对于调用 API 的 Python UDF()和 Remote Function,还需启用
WITH CONNECTION(Remote Function 还需启用bigqueryconnection.googleapis.com)run.googleapis.com
bashCLOUDSDK_METRICS_REQUEST_ATTRIBUTION="agent-skills/1.0 (skill:bigquery-udfs)" \ gcloud services enable bigquery.googleapis.com \ bigqueryconnection.googleapis.com \ run.googleapis.com --quiet - 对于 SQL、JavaScript 和 Offline Python UDF:
-
验证所需 IAM 角色:
- 所有 UDF:数据集上的 ,以及项目上的
roles/bigquery.dataEditor。roles/bigquery.jobUser - 使用 时(调用 API 的 Python UDF 与 Remote Function):
WITH CONNECTION- UDF 创建者:项目上的 ;通过
roles/bigquery.connectionAdmin向连接服务账号授予项目级 IAM 角色时,还需要GRANT ... ON PROJECT权限,例如resourcemanager.projects.setIamPolicy。roles/resourcemanager.projectIamAdmin - UDF 调用者:连接上的 。
roles/bigquery.connectionUser
- UDF 创建者:项目上的
- 所有 UDF:数据集上的
Core Implementation Patterns
核心实现模式
1. SQL UDFs (Scalar & Templated)
1. SQL UDF(标量函数与模板化函数)
Use for persistent UDFs or
for query-scoped functions. Use for polymorphic parameters:
CREATE OR REPLACE FUNCTIONCREATE TEMP FUNCTIONANY TYPEsql
CREATE OR REPLACE FUNCTION `{project_id}.{dataset_id}.normalize_phone`(
raw_phone STRING,
country_code ANY TYPE
)
RETURNS STRING
AS (
CONCAT('+', CAST(country_code AS STRING), '-', REGEXP_REPLACE(raw_phone, r'[^0-9]', ''))
);See SQL and JavaScript UDFs for aggregate UDFs
() and JavaScript Cloud Storage library loading.
CREATE AGGREGATE FUNCTION对于持久化 UDF,使用 ;对于查询作用域函数,使用 。多态参数使用 :
CREATE OR REPLACE FUNCTIONCREATE TEMP FUNCTIONANY TYPEsql
CREATE OR REPLACE FUNCTION `{project_id}.{dataset_id}.normalize_phone`(
raw_phone STRING,
country_code ANY TYPE
)
RETURNS STRING
AS (
CONCAT('+', CAST(country_code AS STRING), '-', REGEXP_REPLACE(raw_phone, r'[^0-9]', ''))
);请参阅 SQL 和 JavaScript UDF,了解聚合 UDF()和 JavaScript Cloud Storage 库加载。
CREATE AGGREGATE FUNCTION2. JavaScript UDFs
2. JavaScript UDF
Use raw triple-quoted strings () to avoid escaping backslashes:
r"""..."""sql
CREATE OR REPLACE FUNCTION `{project_id}.{dataset_id}.extract_url_query_keys`(
url_str STRING
)
RETURNS ARRAY<STRING>
DETERMINISTIC
LANGUAGE js
OPTIONS (
library = ['gs://{bucket_name}/libs/uri-parser.js']
)
AS r"""
if (!url_str) return [];
try {
return URIParser.getQueryKeys(url_str);
} catch (err) {
return [];
}
""";使用原始三引号字符串()以避免转义反斜杠:
r"""..."""sql
CREATE OR REPLACE FUNCTION `{project_id}.{dataset_id}.extract_url_query_keys`(
url_str STRING
)
RETURNS ARRAY<STRING>
DETERMINISTIC
LANGUAGE js
OPTIONS (
library = ['gs://{bucket_name}/libs/uri-parser.js']
)
AS r"""
if (!url_str) return [];
try {
return URIParser.getQueryKeys(url_str);
} catch (err) {
return [];
}
""";3. Managed Python UDFs (With and Without Connection)
3. 托管 Python UDF(使用和不使用 Connection)
Python UDFs must be persistent (do not use ), specify , and define an . , , and
are pre-installed in the base image.
TEMPruntime_version = 'python-3.11'entry_pointnumpypandaspyarrowpython-3.11BigQuery defaults to , , and
. Omit these options when the defaults are
sufficient, and configure them explicitly only when a workload requires custom
container sizing or concurrency (see Python UDFs).
container_memory = '512Mi'container_cpu = 1.0container_request_concurrency = 80Top-level Python statements (, helper functions, classes, and ) inside must have zero leading
indentation (flush to the left margin). Indenting top-level Python definitions
to align with surrounding SQL causes an when BigQuery loads
the container module.
importdef {entry_point}(...)AS r'''...'''IndentationErrorPython UDF 必须是持久化函数(不要使用 ),需要指定 并定义 。、 和 已预装在 基础镜像中。
TEMPruntime_version = 'python-3.11'entry_pointnumpypandaspyarrowpython-3.11BigQuery 默认使用 、 和 。如果默认值已足够,则省略这些选项;仅当工作负载需要自定义容器规格或并发度时才显式配置(请参阅 Python UDF)。
container_memory = '512Mi'container_cpu = 1.0container_request_concurrency = 80AS r'''...'''importdef {entry_point}(...)IndentationErrorA. Offline / Vectorized Python UDF (No Connection Needed)
A. Offline / 向量化 Python UDF(无需 Connection)
Omit when the UDF only performs computation or uses PyPI
packages () / Cloud Storage libraries ().
To vectorize execution over batches of rows, annotate the parameter with
(or ) and return a :
WITH CONNECTIONpackages=[...]library=['gs://...']pd.DataFramepyarrow.RecordBatchpd.Series[!WARNING] Vectorized operations must be row-independent: BigQuery calls vectorized UDFs on arbitrary row batches (up to). Do NOT compute global column statistics (such as z-scores, dataset mean/std, or rank) acrossmax_batching_rows, because each batch only sees an arbitrary slice of rows. Use SQL window functions (df) for dataset-wide statistics. Vectorized Python UDFs should perform row-independent calculations (e.g. geometric distances or multi-column math).(val - AVG(val) OVER()) / NULLIF(STDDEV(val) OVER(), 0)
sql
CREATE OR REPLACE FUNCTION `{project_id}.{dataset_id}.vectorized_distance`(
x1 FLOAT64, y1 FLOAT64, x2 FLOAT64, y2 FLOAT64
)
RETURNS FLOAT64
LANGUAGE python
OPTIONS (
runtime_version = 'python-3.11',
entry_point = 'compute_distance'
)
AS r'''
import numpy as np
import pandas as pd
def compute_distance(df: pd.DataFrame) -> pd.Series:
return pd.Series(
np.hypot(df['x2'] - df['x1'], df['y2'] - df['y1']),
index=df.index,
)
''';当 UDF 仅执行计算或使用 PyPI 包()/ Cloud Storage 库()时,省略 。
若要按批次对执行进行向量化,请使用 标注参数(或使用 ),并返回 :
packages=[...]library=['gs://...']WITH CONNECTIONpd.DataFramepyarrow.RecordBatchpd.Series[!WARNING] 向量化操作必须与行无关:BigQuery 会使用任意行批次(最多)调用向量化 UDF。不要跨max_batching_rows计算全局列统计量(例如 z-score、数据集均值/标准差或排名),因为每个批次只能看到任意一部分行。对于数据集范围的统计量,请使用 SQL 窗口函数(df)。向量化 Python UDF 应执行与行无关的计算(例如几何距离或多列数学运算)。(val - AVG(val) OVER()) / NULLIF(STDDEV(val) OVER(), 0)
sql
CREATE OR REPLACE FUNCTION `{project_id}.{dataset_id}.vectorized_distance`(
x1 FLOAT64, y1 FLOAT64, x2 FLOAT64, y2 FLOAT64
)
RETURNS FLOAT64
LANGUAGE python
OPTIONS (
runtime_version = 'python-3.11',
entry_point = 'compute_distance'
)
AS r'''
import numpy as np
import pandas as pd
def compute_distance(df: pd.DataFrame) -> pd.Series:
return pd.Series(
np.hypot(df['x2'] - df['x1'], df['y2'] - df['y1']),
index=df.index,
)
''';B. Online Python UDF Calling an External / Cloud API (WITH CONNECTION
)
WITH CONNECTIONB. 调用外部或 Cloud API 的 Online Python UDF(WITH CONNECTION
)
WITH CONNECTIONInclude only when the Python code makes outbound network
or API calls at runtime.
WITH CONNECTIONAlways configure explicit timeouts, logging, and prescriptive exception handling
in the block:
try...except- Transient errors only → : Catch retryable exceptions (
NULL,google.api_core.exceptions.TooManyRequests,ServiceUnavailable,DeadlineExceeded, andInternalServerError), log them withRetryError, and returnlogging.warningso a transient blip does not abort the query. Do not catch the base classNonehere: it also matchesGoogleAPICallError,PermissionDenied, andUnauthenticated.InvalidArgument - Fatal errors → raise: Let auth, permission, and invalid-argument errors
propagate (or log and re-raise as ) so they surface as a user error on the query instead of silently producing
RuntimeErrors.NULL - Never log row values: Anyone with Cloud Logging access can read UDF logs
regardless of BigQuery table permissions. Log exception types and messages,
not input or output data. Logs are only emitted when the session sets .
SET @@udf.properties = JSON '{"enableDebugOutput": true}'; - Set a per-request :
timeoutonly caps the total retry duration; also passRetry(timeout=...)on each client call.timeout=
-
Create a Cloud Resource Connection and Retrieve its Service Account:bash
bq mk --connection --connection_type=CLOUD_RESOURCE \ --location={region} --project_id={project_id} {connection_id} bq show --connection {project_id}.{region}.{connection_id} -
Grant Permissions to the Connection Service Account: Granton
roles/serviceusage.serviceUsageConsumerplus the required API role (e.g.,{project_id}) on the target project. Runningroles/cloudtranslate.usermodifies the project's IAM policy and requiresGRANT ... ON PROJECT(for example,resourcemanager.projects.setIamPolicy); confirm with the user before running project-level IAM grants. The DCLroles/resourcemanager.projectIamAdmingrantee takes the connection path (connection:), not the service account email; BigQuery resolves the connection's service account automatically (use[project_id.]location.connection_idto grant by email instead):"serviceAccount:{connection_sa_email}"sqlGRANT `roles/serviceusage.serviceUsageConsumer` ON PROJECT `{project_id}` TO "connection:{project_id}.{region}.{connection_id}"; GRANT `roles/cloudtranslate.user` ON PROJECT `{project_id}` TO "connection:{project_id}.{region}.{connection_id}"; -
Create the Python UDF with(keep top-level Python statements flush-left at column 0):
WITH CONNECTION
sql
CREATE OR REPLACE FUNCTION `{project_id}.{dataset_id}.translate_to_es`(
text STRING
)
RETURNS STRING
LANGUAGE python
WITH CONNECTION `{project_id}.{region}.{connection_id}`
OPTIONS (
entry_point = 'do_translate',
runtime_version = 'python-3.11',
packages = ['google-cloud-translate>=3.11', 'google-api-core']
)
AS r'''
import logging
from google.api_core import exceptions
from google.api_core.retry import Retry
from google.cloud import translate
client = translate.TranslationServiceClient()
TRANSIENT_ERRORS = (
exceptions.TooManyRequests,
exceptions.ServiceUnavailable,
exceptions.DeadlineExceeded,
exceptions.InternalServerError,
exceptions.RetryError,
)
def do_translate(text: str) -> str:
if not text:
return None
try:
# Note: Replace {project_id} with your Google Cloud Project ID
response = client.translate_text(
request={
"parent": "projects/{project_id}/locations/us-central1",
"contents": [text],
"target_language_code": "es",
"mime_type": "text/plain",
},
retry=Retry(timeout=30.0), # Total retry budget.
timeout=10.0, # Per-attempt deadline.
)
return response.translations[0].translated_text
except TRANSIENT_ERRORS as e:
# Log the error type only; never log row values.
logging.warning("Transient Translation API error: %s", type(e).__name__)
return None
except exceptions.GoogleAPICallError as e:
# PermissionDenied, Unauthenticated, InvalidArgument, etc. are fatal.
logging.error("Fatal Translation API error: %s: %s", type(e).__name__, e)
raise RuntimeError(f"Translation failed: {type(e).__name__}") from e
''';See Python UDFs for container sizing
(, , ), Cloud
Logging (), and
checking container build status via .
container_cpucontainer_memorycontainer_request_concurrencySET @@udf.properties = JSON '{"enableDebugOutput": true}';INFORMATION_SCHEMA.ROUTINES仅当 Python 代码在运行时发起出站网络或 API 调用时,才包含 。
WITH CONNECTION始终在 块中配置明确的超时、日志和可操作的异常处理:
try...except- 仅瞬时错误 → :捕获可重试异常(
NULL、google.api_core.exceptions.TooManyRequests、ServiceUnavailable、DeadlineExceeded和InternalServerError),使用RetryError记录,并返回logging.warning,这样瞬时故障不会中止查询。不要在此捕获基类None,因为它还会匹配GoogleAPICallError、PermissionDenied和Unauthenticated。InvalidArgument - 致命错误 → 抛出:让身份验证、权限和无效参数错误向上传播(或记录后重新抛出为 ),从而在查询中显示为用户错误,而不是静默产生
RuntimeError。NULL - 绝不记录行值:任何拥有 Cloud Logging 访问权限的人,无论其 BigQuery 表权限如何,都可以读取 UDF 日志。仅记录异常类型和消息,不记录输入或输出数据。仅当会话设置 后才会输出日志。
SET @@udf.properties = JSON '{"enableDebugOutput": true}'; - 设置每次请求的 :
timeout只会限制总重试时长;还必须在每次客户端调用中传入Retry(timeout=...)。timeout=
-
创建 Cloud Resource Connection 并获取其服务账号:bash
bq mk --connection --connection_type=CLOUD_RESOURCE \ --location={region} --project_id={project_id} {connection_id} bq show --connection {project_id}.{region}.{connection_id} -
向 Connection 服务账号授予权限:向授予
{project_id},并在目标项目上授予所需的 API 角色(例如roles/serviceusage.serviceUsageConsumer)。运行roles/cloudtranslate.user会修改项目的 IAM 策略,并要求具备GRANT ... ON PROJECT权限(例如resourcemanager.projects.setIamPolicy);执行项目级 IAM 授权前,务必与用户确认。DCLroles/resourcemanager.projectIamAdmin被授权方使用的是连接路径(connection:),而不是服务账号邮箱;BigQuery 会自动解析连接的服务账号(也可以改用[project_id.]location.connection_id按邮箱授权):"serviceAccount:{connection_sa_email}"sqlGRANT `roles/serviceusage.serviceUsageConsumer` ON PROJECT `{project_id}` TO "connection:{project_id}.{region}.{connection_id}"; GRANT `roles/cloudtranslate.user` ON PROJECT `{project_id}` TO "connection:{project_id}.{region}.{connection_id}"; -
使用创建 Python UDF(Python 顶层语句保持第 0 列顶格):
WITH CONNECTION
sql
CREATE OR REPLACE FUNCTION `{project_id}.{dataset_id}.translate_to_es`(
text STRING
)
RETURNS STRING
LANGUAGE python
WITH CONNECTION `{project_id}.{region}.{connection_id}`
OPTIONS (
entry_point = 'do_translate',
runtime_version = 'python-3.11',
packages = ['google-cloud-translate>=3.11', 'google-api-core']
)
AS r'''
import logging
from google.api_core import exceptions
from google.api_core.retry import Retry
from google.cloud import translate
client = translate.TranslationServiceClient()
TRANSIENT_ERRORS = (
exceptions.TooManyRequests,
exceptions.ServiceUnavailable,
exceptions.DeadlineExceeded,
exceptions.InternalServerError,
exceptions.RetryError,
)
def do_translate(text: str) -> str:
if not text:
return None
try:
# Note: Replace {project_id} with your Google Cloud Project ID
response = client.translate_text(
request={
"parent": "projects/{project_id}/locations/us-central1",
"contents": [text],
"target_language_code": "es",
"mime_type": "text/plain",
},
retry=Retry(timeout=30.0), # Total retry budget.
timeout=10.0, # Per-attempt deadline.
)
return response.translations[0].translated_text
except TRANSIENT_ERRORS as e:
# Log the error type only; never log row values.
logging.warning("Transient Translation API error: %s", type(e).__name__)
return None
except exceptions.GoogleAPICallError as e:
# PermissionDenied, Unauthenticated, InvalidArgument, etc. are fatal.
logging.error("Fatal Translation API error: %s: %s", type(e).__name__, e)
raise RuntimeError(f"Translation failed: {type(e).__name__}") from e
''';请参阅 Python UDF,了解容器规格配置(、、)、Cloud Logging(),以及如何通过 检查容器构建状态。
container_cpucontainer_memorycontainer_request_concurrencySET @@udf.properties = JSON '{"enableDebugOutput": true}';INFORMATION_SCHEMA.ROUTINES4. Remote Functions (Cloud Run Endpoints)
4. Remote Function(Cloud Run 端点)
Use Remote Functions when the endpoint is hosted on Cloud Run or Cloud Run
functions (for non-Python languages, VPC networking, or custom hardware):
-
Grantto the Connection Service Account (confirm with the user before modifying the Cloud Run service IAM policy):
roles/run.invokerbashCLOUDSDK_METRICS_REQUEST_ATTRIBUTION="agent-skills/1.0 (skill:bigquery-udfs)" \ gcloud run services add-iam-policy-binding {cloud_run_service} \ --region={region} \ --member="serviceAccount:{connection_sa_email}" \ --role="roles/run.invoker" -
Register the Remote Function: The endpoint must acceptand return
{"calls": [[arg1, ...], ...]}with matching element count:{"replies": [res1, ...]}sqlCREATE OR REPLACE FUNCTION `{project_id}.{dataset_id}.enrich_address`( street STRING, postal_code STRING ) RETURNS JSON REMOTE WITH CONNECTION `{project_id}.{region}.{connection_id}` OPTIONS ( endpoint = 'https://{cloud_run_service_url}', max_batching_rows = 1000 );
See Remote Functions for Cloud Run handler
templates and retry handling.
当端点托管于 Cloud Run 或 Cloud Run functions 上,或需要非 Python 语言、VPC 网络或自定义硬件时,使用 Remote Function:
-
向 Connection 服务账号授予(在修改 Cloud Run 服务的 IAM 策略前,先与用户确认):
roles/run.invokerbashCLOUDSDK_METRICS_REQUEST_ATTRIBUTION="agent-skills/1.0 (skill:bigquery-udfs)" \ gcloud run services add-iam-policy-binding {cloud_run_service} \ --region={region} \ --member="serviceAccount:{connection_sa_email}" \ --role="roles/run.invoker" -
注册 Remote Function:端点必须接受,并返回
{"calls": [[arg1, ...], ...]},且两个数组的元素数量必须一致:{"replies": [res1, ...]}
sql
CREATE OR REPLACE FUNCTION `{project_id}.{dataset_id}.enrich_address`(
street STRING, postal_code STRING
)
RETURNS JSON
REMOTE WITH CONNECTION `{project_id}.{region}.{connection_id}`
OPTIONS (
endpoint = 'https://{cloud_run_service_url}',
max_batching_rows = 1000
);请参阅 Remote Function,了解 Cloud Run handler 模板和重试处理。
Validation Checklist
验证清单
After generating or modifying a UDF, follow this validate→fix→repeat loop:
-
Step 1 — Validate Python code before BigQuery DDL: For Python UDFs, validate the Python function anddependencies before submitting the BigQuery DDL—either locally with
packagestest inputs (python3, edge cases,Nonebatches) or in a containerized Cloud Run Job (pd.DataFrameandgcloud run jobs deploy {job_name} --source . --region={region}; see Python UDFs Validation).gcloud run jobs execute {job_name} --region={region} --wait -
Step 2 — Execute DDL and poll container build status: Run. Because the DDL statement returns before the Python container image finishes building, poll
CREATE OR REPLACE FUNCTIONuntilINFORMATION_SCHEMA.ROUTINEStransitions frombuild_statetoIN_PROGRESS(or fix and re-run ifSUCCEEDED):FAILEDsqlSELECT build_status.* FROM `{project_id}.{dataset_id}`.INFORMATION_SCHEMA.ROUTINES WHERE routine_name = '{udf_name}'; -
Step 3 — Test the UDF with SQL: Once
SELECT(or immediately after DDL for SQL/JS UDFs), run a testbuild_state = 'SUCCEEDED'query coveringSELECTand valid inputs.NULL
生成或修改 UDF 后,请遵循“验证 → 修复 → 重复”的循环:
- 步骤 1 — 在 BigQuery DDL 之前验证 Python 代码:对于 Python UDF,在提交 BigQuery DDL 之前验证 Python 函数及 依赖项——可以在本地使用
packages配合测试输入(python3、边界用例、None批次)进行验证,也可以使用容器化的 Cloud Run Job(pd.DataFrame和gcloud run jobs deploy {job_name} --source . --region={region};请参阅 Python UDF 验证)。gcloud run jobs execute {job_name} --region={region} --wait - 步骤 2 — 执行 DDL 并轮询容器构建状态:运行 。由于 DDL 语句会在 Python 容器镜像构建完成之前返回,因此需轮询
CREATE OR REPLACE FUNCTION,直至INFORMATION_SCHEMA.ROUTINES从build_state转换为IN_PROGRESS(如果为SUCCEEDED,则修复后重新运行):FAILED
sql
SELECT build_status.*
FROM `{project_id}.{dataset_id}`.INFORMATION_SCHEMA.ROUTINES
WHERE routine_name = '{udf_name}';- 步骤 3 — 使用 SQL 测试 UDF:当
SELECT时(SQL/JS UDF 则可在执行 DDL 后立即测试),运行覆盖build_state = 'SUCCEEDED'和有效输入的测试NULL查询。SELECT
Cleanup & Teardown
清理与拆除
Delete unused routines, connections, Cloud Run services, and staged Cloud
Storage artifacts (note that the size of all Python UDF containers per project
and per region is restricted to a sum total of 10 GiB):
bash
bq query --use_legacy_sql=false "DROP FUNCTION IF EXISTS \`{project_id}.{dataset_id}.{udf_name}\`;"
bq rm --connection --location={region} {connection_id}
CLOUDSDK_METRICS_REQUEST_ATTRIBUTION="agent-skills/1.0 (skill:bigquery-udfs)" \
gcloud run services delete {cloud_run_service} --region={region} --project={project_id}
CLOUDSDK_METRICS_REQUEST_ATTRIBUTION="agent-skills/1.0 (skill:bigquery-udfs)" \
gcloud storage rm gs://{bucket_name}/udf_libs/bundle.js删除未使用的例程、连接、Cloud Run 服务及已暂存的 Cloud Storage 构件(请注意,每个项目、每个区域的所有 Python UDF 容器总大小限制为 10 GiB):
bash
bq query --use_legacy_sql=false "DROP FUNCTION IF EXISTS \`{project_id}.{dataset_id}.{udf_name}\`;"
bq rm --connection --location={region} {connection_id}
CLOUDSDK_METRICS_REQUEST_ATTRIBUTION="agent-skills/1.0 (skill:bigquery-udfs)" \
gcloud run services delete {cloud_run_service} --region={region} --project={project_id}
CLOUDSDK_METRICS_REQUEST_ATTRIBUTION="agent-skills/1.0 (skill:bigquery-udfs)" \
gcloud storage rm gs://{bucket_name}/udf_libs/bundle.jsReference Directory
参考目录
- SQL and JavaScript UDFs: Templated SQL
parameters (), aggregate UDFs, JavaScript type mappings, and Cloud Storage library loading (
ANY TYPE).https://docs.cloud.google.com/bigquery/docs/user-defined-functions.md.txt - Python UDFs: Offline vs. online service access, Pandas/PyArrow vectorization, container resource limits (
WITH CONNECTION/container_cpu), and Cloud Logging debugging (container_memory).https://docs.cloud.google.com/bigquery/docs/user-defined-functions-python.md.txt - Remote Functions: Cloud Run HTTP request
and response JSON schema, batch sizing, retry semantics, and VPC egress
().
https://docs.cloud.google.com/bigquery/docs/remote-functions.md.txt - IAM, Authorized Routines, and Quotas:
Sharing routines across datasets (), container quotas, and troubleshooting errors.
Authorized Routines
- SQL 和 JavaScript UDF:模板化 SQL 参数()、聚合 UDF、JavaScript 类型映射和 Cloud Storage 库加载(
ANY TYPE)。https://docs.cloud.google.com/bigquery/docs/user-defined-functions.md.txt - Python UDF:Offline 与通过 进行的在线服务访问、Pandas/PyArrow 向量化、容器资源限制(
WITH CONNECTION/container_cpu)以及 Cloud Logging 调试(container_memory)。https://docs.cloud.google.com/bigquery/docs/user-defined-functions-python.md.txt - Remote Function:Cloud Run HTTP 请求和响应 JSON 模式、批处理大小、重试语义及 VPC 出口()。
https://docs.cloud.google.com/bigquery/docs/remote-functions.md.txt - IAM、Authorized Routines 与配额:跨数据集共享例程(Authorized Routines)、容器配额和错误排查。
Related Skills
相关 Skill
- BigQuery Basics (): Dataset, table, and job management.
bigquery-basics - BigQuery DataFrames: Creating Python UDFs from
Python via .
@bpd.udf - BigQuery AI & ML: Built-in and
ML.GENERATE_TEXTfunctions.AI.GENERATE
- BigQuery Basics():数据集、表和作业管理。
bigquery-basics - BigQuery DataFrames:通过 从 Python 创建 Python UDF。
@bpd.udf - BigQuery AI & ML:内置 和
ML.GENERATE_TEXT函数。AI.GENERATE