更新视图属性

本文档介绍如何更新视图属性或元数据。创建视图后,您可以更新以下视图属性:

所需权限

如需更新视图,您至少必须具有 bigquery.tables.updatebigquery.tables.get 权限。如果要更新视图的 SQL 查询,您还必须有权限查询视图的 SQL 查询所引用的任何表。

以下预定义的 IAM 角色具有 bigquery.tables.updatebigquery.tables.get 权限:

  • bigquery.dataEditor
  • bigquery.dataOwner
  • bigquery.admin

此外,如果用户具有 bigquery.datasets.create 权限,则当该用户创建数据集时,系统会为其授予该数据集的 bigquery.dataOwner 访问权限。借助 bigquery.dataOwner 访问权限,用户可以更新数据集内的表和视图。

如需详细了解 BigQuery 中的 IAM 角色和权限,请参阅预定义的角色和权限

更新视图的 SQL 查询

您可以通过以下方式更新用于定义视图的 SQL 查询:

  • 使用 Cloud Console 或经典版 BigQuery 网页界面
  • 使用 bq 命令行工具的 bq update 命令
  • 调用 tables.patch API 方法
  • 使用客户端库

您可以在 API 或 bq 命令行工具中将 SQL 方言从旧版 SQL 更改为标准 SQL。您无法在 Cloud Console 或经典版 BigQuery 网页界面中将旧版 SQL 视图更新为标准 SQL。

要更新视图的 SQL 查询,请执行以下操作:

控制台

  1. 资源面板中,展开项目和数据集,然后选择视图。

  2. 点击详情标签页。

    查看详细信息

  3. 查询框上方,点击修改查询按钮。在随即显示的对话框中点击打开

    修改查询

  4. 查询编辑器框中修改 SQL 查询,然后点击保存视图

    保存视图

  5. 确保保存视图对话框中的所有字段都正确无误,然后点击保存

经典版界面

  1. 选择视图。

  2. 视图详细信息 (View Details) 面板中,点击详细信息

  3. 查询框下方,点击修改查询

  4. Query 框中修改查询,然后点击 Save View

    更新视图

bq

发出带 --view 标志的 bq update 命令。如需使用标准 SQL 或者将查询方言从旧版 SQL 更新为标准 SQL,请包含 --use_legacy_sql 标志并将其设置为 false

如果您的查询引用了存储在 Google Cloud Storage 或本地文件中的外部用户定义函数资源,请使用 --view_udf_resource 标志指定这些资源。此处未显示 --view_udf_resource 标志。如需详细了解如何使用用户指定函数 (UDF),请参阅标准 SQL 用户指定函数

如果您要更新非默认项目中的视图,请按以下格式将项目 ID 添加到数据集名称中:project_id:dataset

bq update \
--use_legacy_sql=false \
--view_udf_resource=path_to_file \
--view='query' \
project_id:dataset.view

其中:

  • path_to_file 是一个代码文件的 URI 或本地文件系统路径,该代码文件会立即作为视图使用的用户定义函数资源进行加载和评估。重复使用该标志可指定多个文件。
  • query 是一条有效的标准 SQL 查询。
  • project_id 是项目 ID。
  • dataset 是包含相应视图的数据集。
  • view 是要更新的视图的名称。

示例:

输入以下命令以更新 mydataset 中名为 myview 的视图的 SQL 查询。mydataset 属于默认项目。用于更新视图的示例查询会从美国姓名数据公开数据集中查询数据。

bq update \
--use_legacy_sql=false \
--view \
'SELECT
  name,
  number
FROM
  `bigquery-public-data.usa_names.usa_1910_current`
WHERE
  gender = "M"
ORDER BY
  number DESC' \
mydataset.myview

输入以下命令以更新 mydataset 中名为 myview 的视图的 SQL 查询。mydataset 属于 myotherproject,而非默认项目。用于更新视图的示例查询会从美国姓名数据公开数据集中查询数据。

bq update \
--use_legacy_sql=false \
--view \
'SELECT
  name,
  number
FROM
  `bigquery-public-data.usa_names.usa_1910_current`
WHERE
  gender = "M"
ORDER BY
  number DESC' \
myotherproject:mydataset.myview

API

要更新视图,可使用包含已更新的 view 属性的表资源调用 tables.patch 方法。由于 tables.update 方法会替换整个表资源,因此最好使用 tables.patch 方法。

Go

在尝试此示例之前,请按照《BigQuery 快速入门:使用客户端库》中的 Go 设置说明进行操作。如需了解详情,请参阅 BigQuery Go API 参考文档

import (
	"context"
	"fmt"

	"cloud.google.com/go/bigquery"
)

// updateView demonstrates updating the query metadata that defines a logical view.
func updateView(projectID, datasetID, viewID string) error {
	// projectID := "my-project-id"
	// datasetID := "mydataset"
	// viewID := "myview"
	ctx := context.Background()
	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %v", err)
	}
	defer client.Close()

	view := client.Dataset(datasetID).Table(viewID)
	meta, err := view.Metadata(ctx)
	if err != nil {
		return err
	}

	newMeta := bigquery.TableMetadataToUpdate{
		// This example updates a view into the shakespeare dataset to exclude works named after kings.
		ViewQuery: "SELECT word, word_count, corpus, corpus_date FROM `bigquery-public-data.samples.shakespeare` WHERE corpus NOT LIKE '%king%'",
	}

	if _, err := view.Update(ctx, newMeta, meta.ETag); err != nil {
		return err
	}
	return nil
}

Java

试用此示例之前,请按照《BigQuery 快速入门:使用客户端库》中的 Java 设置说明进行操作。 如需了解详情,请参阅 BigQuery Java API 参考文档

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.TableId;
import com.google.cloud.bigquery.TableInfo;
import com.google.cloud.bigquery.ViewDefinition;

// Sample to update query on a view
public class UpdateViewQuery {

  public static void runUpdateViewQuery() {
    // TODO(developer): Replace these variables before running the sample.
    String datasetName = "MY_DATASET_NAME";
    String tableName = "MY_TABLE_NAME";
    String viewName = "MY_VIEW_NAME";
    String updateQuery =
        String.format("SELECT TimestampField, StringField FROM %s.%s", datasetName, tableName);
    updateViewQuery(datasetName, viewName, updateQuery);
  }

  public static void updateViewQuery(String datasetName, String viewName, String query) {
    try {
      // Initialize client that will be used to send requests. This client only needs to be created
      // once, and can be reused for multiple requests.
      BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

      // Retrieve existing view metadata
      TableInfo viewMetadata = bigquery.getTable(TableId.of(datasetName, viewName));

      // Update view query
      ViewDefinition viewDefinition = viewMetadata.getDefinition();
      viewDefinition.toBuilder().setQuery(query).build();

      // Set metadata
      bigquery.update(viewMetadata.toBuilder().setDefinition(viewDefinition).build());

      System.out.println("View query updated successfully");
    } catch (BigQueryException e) {
      System.out.println("View query was not updated. \n" + e.toString());
    }
  }
}

Node.js

在尝试此示例之前,请按照《BigQuery 快速入门:使用客户端库》中的 Node.js 设置说明进行操作。如需了解详情,请参阅 BigQuery Node.js API 参考文档

// Import the Google Cloud client library and create a client
const {BigQuery} = require('@google-cloud/bigquery');
const bigquery = new BigQuery();

async function updateViewQuery() {
  // Updates a view named "my_existing_view" in "my_dataset".

  /**
   * TODO(developer): Uncomment the following lines before running the sample.
   */
  // const datasetId = "my_existing_dataset"
  // const tableId = "my_existing_table"
  const dataset = await bigquery.dataset(datasetId);

  // This example updates a view into the USA names dataset to include state.
  const newViewQuery = `SELECT name, state
  FROM \`bigquery-public-data.usa_names.usa_1910_current\`
  LIMIT 10`;

  // Retrieve existing view
  const [view] = await dataset.table(tableId).get();

  // Retrieve existing view metadata
  const [metadata] = await view.getMetadata();

  // Uodate view query
  metadata.view = newViewQuery;

  // Set metadata
  await view.setMetadata(metadata);

  console.log(`View ${tableId} updated.`);
}

Python

在尝试此示例之前,请按照《BigQuery 快速入门:使用客户端库》中的 Python 设置说明进行操作。如需了解详情,请参阅 BigQuery Python API 参考文档

# from google.cloud import bigquery
# client = bigquery.Client()
# project = 'my-project'
# source_dataset_id = 'my_source_dataset'
# source_table_id = 'us_states'
# shared_dataset_ref = bigquery.DatasetReference(project, 'my_shared_dataset')

# This example shows how to update a shared view of a source table of
# US States. The view's query will be updated to contain only states with
# names starting with 'M'.
view_ref = shared_dataset_ref.table("my_shared_view")
view = bigquery.Table(view_ref)
sql_template = 'SELECT name, post_abbr FROM `{}.{}.{}` WHERE name LIKE "M%"'
view.view_query = sql_template.format(project, source_dataset_id, source_table_id)
view = client.update_table(view, ["view_query"])  # API request

更新视图的到期时间

您可在数据集级层设置默认表到期时间(这将同时影响表和视图),也可在创建视图时设置视图的到期时间。如果在创建视图时设置到期时间,则会忽略数据集的默认表到期时间。如果未在数据集级层设置默认表到期时间,也未在创建视图时设置到期时间,则该视图永不过期,您必须手动删除该视图。

创建视图后,您可以随时通过以下方式更新视图的到期时间:

  • 使用经典版 BigQuery 网页界面
    • Cloud Console 当前不支持修改视图到期时间
  • 使用 bq 命令行工具的 bq update 命令
  • 调用 tables.patch API 方法
  • 使用客户端库

要更新视图的到期时间,请执行以下操作:

控制台

  1. 在导航窗格中,选择视图。

  2. 在视图的“详细信息”页面上,点击详细信息标签页。

  3. 视图信息右侧,点击修改图标(铅笔)。

  4. 视图信息对话框中,对于视图过期,点击指定日期

  5. 在日期选择器中,输入到期日期和时间,然后点击确定

  6. 点击更新。更新后的到期时间会显示在视图信息部分中。

DDL

借助数据定义语言 (DDL) 语句,您可以使用标准 SQL 查询语法创建和修改表和视图。

详细了解如何使用数据定义语言语句

如需在 Cloud Console 中使用 DDL 语句,请执行以下操作:

  1. 点击编写新查询

  2. 查询编辑器文本区域中,输入您的 DDL 语句。

    ALTER VIEW mydataset.myview
    SET OPTIONS (
    -- Sets view expiration to timestamp 2025-02-03 12:34:56 in the America/Los Angeles time zone
    expiration_timestamp=TIMESTAMP("2025-02-03 12:34:56", "America/Los Angeles")
    );
    
  3. 点击运行查询

经典版界面

  1. 在导航窗格中,选择视图。

  2. View Details 页面上,点击 Details

  3. 对于 Expiration Time,点击 Edit

  4. Update Expiration 对话框中,点击 In,再输入以天为单位的到期时间。

  5. 点击 OK。已更新的到期时间会显示在 Details 页面上。

    视图过期

bq

发出带 --expiration 标志的 bq update 命令。如果您要更新非默认项目中的视图,请按以下格式将项目 ID 添加到数据集名称中:project_id:dataset

bq update \
--expiration integer \
project_id:dataset.view

其中:

  • integer 是表的默认生命周期(以秒为单位)。 最小值为 3600 秒(一小时)。到期时间以当前时间加上这个整数值为准。
  • project_id 是项目 ID。
  • dataset 是包含要更新的视图的数据集的名称。
  • view 是要更新的视图的名称。

示例:

输入以下命令可将 mydatasetmyview 的到期时间更新为 5 天(432000 秒)。mydataset 属于默认项目。

bq update --expiration 432000 mydataset.myview

输入以下命令可将 mydatasetmyview 的到期时间更新为 5 天(432000 秒)。mydataset 属于 myotherproject,而非默认项目。

bq update --expiration 432000 myotherproject:mydataset.myview

API

调用 tables.patch 方法并使用表资源中的 expirationTime 属性。由于 tables.update 方法会替换整个表资源,因此最好使用 tables.patch 方法。使用 REST API 时,视图的到期时间以毫秒为单位表示。

Go

在尝试此示例之前,请按照《BigQuery 快速入门:使用客户端库》中的 Go 设置说明进行操作。如需了解详情,请参阅 BigQuery Go API 参考文档

import (
	"context"
	"fmt"
	"time"

	"cloud.google.com/go/bigquery"
)

// updateTableExpiration demonstrates setting the table expiration of a table to a specific point in time
// in the future, at which time it will be deleted.
func updateTableExpiration(projectID, datasetID, tableID string) error {
	// projectID := "my-project-id"
	// datasetID := "mydataset"
	// tableID := "mytable"
	ctx := context.Background()
	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %v", err)
	}
	defer client.Close()

	tableRef := client.Dataset(datasetID).Table(tableID)
	meta, err := tableRef.Metadata(ctx)
	if err != nil {
		return err
	}
	update := bigquery.TableMetadataToUpdate{
		ExpirationTime: time.Now().Add(time.Duration(5*24) * time.Hour), // table expiration in 5 days.
	}
	if _, err = tableRef.Update(ctx, update, meta.ETag); err != nil {
		return err
	}
	return nil
}

Java

试用此示例之前,请按照《BigQuery 快速入门:使用客户端库》中的 Java 设置说明进行操作。 如需了解详情,请参阅 BigQuery Java API 参考文档

Table beforeTable = bigquery.getTable(datasetName, tableName);

// Set table to expire 5 days from now.
long expirationMillis = DateTime.now().plusDays(5).getMillis();
TableInfo tableInfo = beforeTable.toBuilder()
        .setExpirationTime(expirationMillis)
        .build();
Table afterTable = bigquery.update(tableInfo);

Node.js

在尝试此示例之前,请按照《BigQuery 快速入门:使用客户端库》中的 Node.js 设置说明进行操作。如需了解详情,请参阅 BigQuery Node.js API 参考文档

// Import the Google Cloud client library
const {BigQuery} = require('@google-cloud/bigquery');
const bigquery = new BigQuery();

async function updateTableExpiration() {
  // Updates a table's expiration.

  /**
   * TODO(developer): Uncomment the following lines before running the sample.
   */
  // const datasetId = 'my_dataset', // Existing dataset
  // const tableId = 'my_table', // Existing table
  // const expirationTime = Date.now() + 1000 * 60 * 60 * 24 * 5 // 5 days from current time in ms

  // Retreive current table metadata
  const table = bigquery.dataset(datasetId).table(tableId);
  const [metadata] = await table.getMetadata();

  // Set new table expiration to 5 days from current time
  metadata.expirationTime = expirationTime.toString();
  const [apiResponse] = await table.setMetadata(metadata);

  const newExpirationTime = apiResponse.expirationTime;
  console.log(`${tableId} expiration: ${newExpirationTime}`);
}

Python

更新视图到期时间的过程与更新表到期时间的过程相同。

在尝试此示例之前,请按照《BigQuery 快速入门:使用客户端库》中的 Python 设置说明进行操作。如需了解详情,请参阅 BigQuery Python API 参考文档

import datetime
import pytz

# from google.cloud import bigquery
# client = bigquery.Client()
# project = client.project
# dataset_ref = bigquery.DatasetReference(project, dataset_id)
# table_ref = dataset_ref.table('my_table')
# table = client.get_table(table_ref)  # API request

assert table.expires is None

# set table to expire 5 days from now
expiration = datetime.datetime.now(pytz.utc) + datetime.timedelta(days=5)
table.expires = expiration
table = client.update_table(table, ["expires"])  # API request

# expiration is stored in milliseconds
margin = datetime.timedelta(microseconds=1000)
assert expiration - margin <= table.expires <= expiration + margin

更新视图的说明

您可以通过以下方式更新视图的说明:

  • 使用 Cloud Console 或经典版 BigQuery 网页界面
  • 使用 bq 命令行工具的 bq update 命令
  • 调用 tables.patch API 方法
  • 使用客户端库

要更新视图的说明,请执行以下操作:

控制台

使用 Cloud Console 创建视图时无法添加说明。创建视图后,您可以在详细信息页面上添加说明。

  1. 资源列表中,选择您的视图。

  2. 点击详细信息标签页。

    查看详细信息

  3. 点击说明旁边的铅笔图标。

    修改视图说明

  4. 在对话框中输入说明。点击更新以保存新说明。

DDL

借助数据定义语言 (DDL) 语句,您可以使用标准 SQL 查询语法创建和修改表和视图。

详细了解如何使用数据定义语言语句

如需在 Cloud Console 中使用 DDL 语句,请执行以下操作:

  1. 点击编写新查询

  2. 查询编辑器文本区域中,输入您的 DDL 语句。

     ALTER VIEW mydataset.myview
     SET OPTIONS (
       description="Description of myview"
     );
     

  3. 点击运行查询

经典版界面

  1. 在导航窗格中,选择视图。

  2. View Details 页面上,点击 Details

  3. 说明部分,点击说明此视图 (Describe this view) 以打开说明框。

  4. 在该框中输入说明。在框外点击一下即可保存文本。

    表的说明

bq

发出带 --description 标志的 bq update 命令。如果您要更新非默认项目中的视图,请按以下格式将项目 ID 添加到数据集名称中:[PROJECT_ID]:[DATASET]

bq update \
--description "description" \
project_id:dataset.view

其中:

  • description 是说明视图的文字,括在英文引号之间。
  • project_id 是项目 ID。
  • dataset 是包含要更新的视图的数据集的名称。
  • view 是要更新的视图的名称。

示例:

输入以下命令,将 mydatasetmyview 的说明更改为“Description of myview”。mydataset 属于默认项目。

bq update --description "Description of myview" mydataset.myview

输入以下命令,将 mydatasetmyview 的说明更改为“Description of myview”。mydataset 属于 myotherproject,而非默认项目。

bq update \
--description "Description of myview" \
myotherproject:mydataset.myview

API

调用 tables.patch 方法并使用 description 属性更新表资源中的视图说明。由于 tables.update 方法会替换整个表资源,因此最好使用 tables.patch 方法。

Go

在尝试此示例之前,请按照《BigQuery 快速入门:使用客户端库》中的 Go 设置说明进行操作。如需了解详情,请参阅 BigQuery Go API 参考文档

import (
	"context"
	"fmt"

	"cloud.google.com/go/bigquery"
)

// updateTableDescription demonstrates how to fetch a table's metadata and updates the Description metadata.
func updateTableDescription(projectID, datasetID, tableID string) error {
	// projectID := "my-project-id"
	// datasetID := "mydataset"
	// tableID := "mytable"
	ctx := context.Background()
	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %v", err)
	}
	defer client.Close()

	tableRef := client.Dataset(datasetID).Table(tableID)
	meta, err := tableRef.Metadata(ctx)
	if err != nil {
		return err
	}
	update := bigquery.TableMetadataToUpdate{
		Description: "Updated description.",
	}
	if _, err = tableRef.Update(ctx, update, meta.ETag); err != nil {
		return err
	}
	return nil
}

Java

更新视图说明的过程与更新表说明的过程相同。

试用此示例之前,请按照《BigQuery 快速入门:使用客户端库》中的 Java 设置说明进行操作。 如需了解详情,请参阅 BigQuery Java API 参考文档

// String datasetName = "my_dataset_name";
// String tableName = "my_table_name";
// String newDescription = "new_description";

Table beforeTable = bigquery.getTable(datasetName, tableName);
TableInfo tableInfo = beforeTable.toBuilder()
    .setDescription(newDescription)
    .build();
Table afterTable = bigquery.update(tableInfo);

Node.js

在尝试此示例之前,请按照《BigQuery 快速入门:使用客户端库》中的 Node.js 设置说明进行操作。如需了解详情,请参阅 BigQuery Node.js API 参考文档

// Import the Google Cloud client library
const {BigQuery} = require('@google-cloud/bigquery');
const bigquery = new BigQuery();

async function updateTableDescription() {
  // Updates a table's description.

  // Retreive current table metadata
  const table = bigquery.dataset(datasetId).table(tableId);
  const [metadata] = await table.getMetadata();

  // Set new table description
  const description = 'New table description.';
  metadata.description = description;
  const [apiResponse] = await table.setMetadata(metadata);
  const newDescription = apiResponse.description;

  console.log(`${tableId} description: ${newDescription}`);
}

Python

更新视图说明的过程与更新表说明的过程相同。

在尝试此示例之前,请按照《BigQuery 快速入门:使用客户端库》中的 Python 设置说明进行操作。如需了解详情,请参阅 BigQuery Python API 参考文档

# from google.cloud import bigquery
# client = bigquery.Client()
# project = client.project
# dataset_ref = bigquery.DatasetReference(project, dataset_id)
# table_ref = dataset_ref.table('my_table')
# table = client.get_table(table_ref)  # API request

assert table.description == "Original description."
table.description = "Updated description."

table = client.update_table(table, ["description"])  # API request

assert table.description == "Updated description."

后续步骤