Work with user-defined functions in Python
A Python user-defined function (UDF) lets you implement a scalar function in Python and use it in a SQL query. Python UDFs are similar to SQL and Javascript UDFs, but with additional capabilities. Python UDFs let you install third-party libraries from the Python Package Index (PyPI) and let you access external services using a Cloud resource connection.
Python UDFs are built and run on BigQuery managed resources.
Limitations
python-3.11is the only supported runtime.- You can't create a temporary Python UDF.
- You can't use a Python UDF with a materialized view.
- The results of a query that calls a Python UDF aren't cached because the return value of a Python UDF is always assumed to be non-deterministic.
- Assured workloads aren't supported.
- These data types are not supported:
JSON,RANGE,INTERVAL, andGEOGRAPHY. - Containers that run Python UDFs can only be configured up to 4 vCpu and 16 GiB.
- Encrypting Python UDF code with Customer-managed encryption keys (CMEK) isn't supported.
- Python UDFs support VPC Service Controls, but VPC networks aren't supported.
Required roles
The required IAM roles are based on whether you are a Python UDF owner or a Python UDF user.
UDF owners
A Python UDF owner typically creates or updates a UDF. Additional roles are also
required if you create a Python UDF that references a Cloud resource connection.
This connection is required only if your UDF uses the
WITH CONNECTION clause to access
an external service.
To get the permissions that you need to create or update a Python UDF, ask your administrator to grant you the following IAM roles:
- BigQuery Data Editor (
roles/bigquery.dataEditor) on the dataset - BigQuery Job User (
roles/bigquery.jobUser) on the project - BigQuery Connection Admin (
roles/bigquery.connectionAdmin) on the project
For more information about granting roles, see Manage access to projects, folders, and organizations.
These predefined roles contain the permissions required to create or update a Python UDF. To see the exact permissions that are required, expand the Required permissions section:
Required permissions
The following permissions are required to create or update a Python UDF:
-
Create a Python UDF using the
CREATE FUNCTIONstatement:bigquery.routines.createon the dataset -
Update a Python UDF using the
CREATE FUNCTIONstatement:bigquery.routines.updateon the dataset -
Run a
CREATE FUNCTIONstatement query job:bigquery.jobs.createon the project -
Create a new Cloud resource connection:
bigquery.connections.createon the project -
Use a connection in the
CREATE FUNCTIONstatement:bigquery.connections.delegateon the connection
You might also be able to get these permissions with custom roles or other predefined roles.
For more information about roles in BigQuery, see Predefined IAM roles.
UDF users
A Python UDF user invokes a UDF created by someone else. Additional roles are also required if you invoke a Python UDF that references a Cloud resource connection.
To get the permissions that you need to invoke a Python UDF created by someone else, ask your administrator to grant you the following IAM roles:
- BigQuery User (
roles/bigquery.user) on the project - BigQuery Data Viewer (
roles/bigquery.dataViewer) on the dataset - BigQuery Connection User (
roles/bigquery.connectionUser) on the connection
For more information about granting roles, see Manage access to projects, folders, and organizations.
These predefined roles contain the permissions required to invoke a Python UDF created by someone else. To see the exact permissions that are required, expand the Required permissions section:
Required permissions
The following permissions are required to invoke a Python UDF created by someone else:
-
To run a query job that references a Python UDF:
bigquery.jobs.createon the project -
To invoke a Python UDF created by someone else:
bigquery.routines.geton the dataset -
To run a Python UDF that references a Cloud resource connection:
bigquery.connections.useon the connection
You might also be able to get these permissions with custom roles or other predefined roles.
For more information about roles in BigQuery, see Predefined IAM roles.
Create a persistent Python UDF
Follow these rules when you create a Python UDF:
The body of the Python UDF must be a quoted string literal that represents the Python code. To learn more about quoted string literals, see Formats for quoted literals.
The body of the Python UDF must include a Python function that is used in the
entry_pointargument in the Python UDF options list.A Python runtime version needs to be specified in the
runtime_versionoption. The only supported Python runtime version ispython-3.11. For a full list of available options, see the Function option list for theCREATE FUNCTIONstatement.
To create a persistent Python UDF, use the CREATE FUNCTION statement
without the TEMP or TEMPORARY keyword. To delete a persistent Python UDF,
use the DROP FUNCTION statement.
Example
To see an example of creating a persistent Python UDF, choose on of the following options:
Console
The following example creates a persistent Python UDF named multiplyInputs
and calls the UDF from within a SELECT statement:
Go to the BigQuery page.
In the query editor, enter the following
CREATE FUNCTIONstatement:CREATE FUNCTION `PROJECT_ID.DATASET_ID`.multiplyInputs(x FLOAT64, y FLOAT64) RETURNS FLOAT64 LANGUAGE python OPTIONS(runtime_version="python-3.11", entry_point="multiply") AS r''' def multiply(x, y): return x * y '''; -- Call the Python UDF. WITH numbers AS (SELECT 1 AS x, 5 as y UNION ALL SELECT 2 AS x, 10 as y UNION ALL SELECT 3 as x, 15 as y) SELECT x, y, `PROJECT_ID.DATASET_ID`.multiplyInputs(x, y) AS product FROM numbers;
Replace PROJECT_ID.DATASET_ID with your project ID and dataset ID.
Click Run.
This example produces the following output:
+-----+-----+--------------+ | x | y | product | +-----+-----+--------------+ | 1 | 5 | 5.0 | | 2 | 10 | 20.0 | | 3 | 15 | 45.0 | +-----+-----+--------------+
BigQuery DataFrames
The following example uses BigQuery DataFrames to turn a custom function into a Python UDF:
Container build status
When you create a Python UDF using the CREATE FUNCTION statement,
BigQuery creates or updates a container image that is based on a
base image. The container is built on the base image using your code and any
specified package dependencies.
Creating the container is a long-running process. The first query after you run
the CREATE FUNCTION statement waits for the image build to complete. If there
are no external dependencies, the container image is typically created in
less than a minute.
The size of all Python UDF containers per project and per region is restricted to a sum total of 10GiB. For more information, see User-defined function limits for persistent UDFs. Your container build fails if your project has reached the quota.
To see the status of your container build, choose one of the following: