对表数据进行分页

本文档介绍如何使用 BigQuery REST API 对表数据进行分页。

通过 API 对结果进行分页

在某些情况下,所有 collection.list 方法都会返回分页的结果。每页的结果数由 maxResults 属性控制。

方法 分页标准 默认的 maxResults 最大 maxResults
Tabledata.list 如果响应所含序列化 JSON 的大小超过 10 MB 或响应数据多于 maxResults 行,则返回分页结果。 10 万 100000
所有其他 collection.list 方法 如果响应数据多于 maxResults 行,则返回分页结果。 50 1000

如果设置的 maxResults 值大于上面列出的最大值,则系统会根据最大值对结果进行分页。

一个页面是总行数的子集。如果结果包含多页数据,则结果数据将具有 pageToken 属性。如需检索下一页结果,请再次调用 list,并通过网址参数“pageToken”来提供标记值。

用于对表数据进行分页的 bigquery.tabledata.list 方法使用行偏移值或页面标记。详情请参阅浏览表数据

以下示例演示了如何对 bigquery 表数据进行分页。

C#

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


using Google.Api.Gax;
using Google.Apis.Bigquery.v2.Data;
using Google.Cloud.BigQuery.V2;
using System;
using System.Collections.Generic;
using System.Linq;

public class BigQueryBrowseTable
{
    public void BrowseTable(
        string projectId = "your-project-id"
    )
    {
        BigQueryClient client = BigQueryClient.Create(projectId);
        TableReference tableReference = new TableReference()
        {
            TableId = "shakespeare",
            DatasetId = "samples",
            ProjectId = "bigquery-public-data"
        };
        // Load all rows from a table
        PagedEnumerable<TableDataList, BigQueryRow> result = client.ListRows(
            tableReference: tableReference,
            schema: null
        );
        // Print the first 10 rows
        foreach (BigQueryRow row in result.Take(10))
        {
            Console.WriteLine($"{row["corpus"]}: {row["word_count"]}");
        }
    }
}

Java

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

TableId tableIdObject = TableId.of(datasetName, tableName);
// This example reads the result 100 rows per RPC call. If there's no need to limit the number,
// simply omit the option.
TableResult tableData =
    bigquery.listTableData(tableIdObject, TableDataListOption.pageSize(100));
for (FieldValueList row : tableData.iterateAll()) {
  // do something with the row
}

Go

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

默认情况下,Go 版 Google Cloud 客户端库会自动分页,因此您无需自行实现分页,例如:

table := client.Dataset(datasetID).Table(tableID)
it := table.Read(ctx)
for {
	var row []bigquery.Value
	err := it.Next(&row)
	if err == iterator.Done {
		break
	}
	if err != nil {
		return err
	}
	fmt.Println(row)
}

Node.js

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

默认情况下,Node.js 版 Google Cloud 客户端库会自动分页,因此您无需自行实现分页,例如:


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

async function browseRows() {
  // Displays rows from "my_table" in "my_dataset".

  /**
   * TODO(developer): Uncomment the following lines before running the sample.
   */
  // const datasetId = "my_dataset";
  // const tableId = "my_table";

  // List rows in the table
  const [rows] = await bigquery
    .dataset(datasetId)
    .table(tableId)
    .getRows();

  console.log('Rows:');
  rows.forEach(row => console.log(row));
}

PHP

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

PHP 版 Google Cloud 客户端库会通过生成器函数 rows 在迭代期间获取下一页的结果,从而实现自动分页。

use Google\Cloud\BigQuery\BigQueryClient;

/** Uncomment and populate these variables in your code */
// $projectId = 'The Google project ID';
// $datasetId = 'The BigQuery dataset ID';
// $tableId   = 'The BigQuery table ID';
// $maxResults = 10;

$maxResults = 10;
$startIndex = 0;

$options = [
    'maxResults' => $maxResults,
    'startIndex' => $startIndex
];
$bigQuery = new BigQueryClient([
    'projectId' => $projectId,
]);
$dataset = $bigQuery->dataset($datasetId);
$table = $dataset->table($tableId);
$numRows = 0;
foreach ($table->rows($options) as $row) {
    print('---');
    foreach ($row as $column => $value) {
        printf('%s: %s' . PHP_EOL, $column, $value);
    }
    $numRows++;
}

Python

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

默认情况下,Python 版 Google Cloud 客户端库会自动分页,因此您无需自行实现分页,例如:

# from google.cloud import bigquery
# client = bigquery.Client()

dataset_ref = client.dataset("samples", project="bigquery-public-data")
table_ref = dataset_ref.table("shakespeare")
table = client.get_table(table_ref)  # API call

# Load all rows from a table
rows = client.list_rows(table)
assert len(list(rows)) == table.num_rows

# Load the first 10 rows
rows = client.list_rows(table, max_results=10)
assert len(list(rows)) == 10

# Specify selected fields to limit the results to certain columns
fields = table.schema[:2]  # first two columns
rows = client.list_rows(table, selected_fields=fields, max_results=10)
assert len(rows.schema) == 2
assert len(list(rows)) == 10

# Use the start index to load an arbitrary portion of the table
rows = client.list_rows(table, start_index=10, max_results=10)

# Print row data in tabular format
format_string = "{!s:<16} " * len(rows.schema)
field_names = [field.name for field in rows.schema]
print(format_string.format(*field_names))  # prints column headers
for row in rows:
    print(format_string.format(*row))  # prints row data

Ruby

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

Ruby 版 Google Cloud 客户端库使用 Table#dataData#next 自动分页。

require "google/cloud/bigquery"

def browse_table
  bigquery = Google::Cloud::Bigquery.new project_id: "bigquery-public-data"
  dataset  = bigquery.dataset "samples"
  table    = dataset.table "shakespeare"

  # Load all rows from a table
  rows = table.data

  # Load the first 10 rows
  rows = table.data max: 10

  # Print row data
  rows.each { |row| puts row }
end

请求任意页面并避免冗余列表调用

当您使用缓存的 pageToken 值向后翻页或跳转到任意页面时,页面中的数据可能自上次查看后已更改,但没有数据可能已更改的明确指示。您可以使用 Etag 属性缓解此问题。

每个 collection.list 方法(Tabledata 除外)都会在结果中返回 Etag 属性。该属性是页面结果的哈希值,可用于验证自上次请求以来页面是否已更改。当使用 Etag 值向 BigQuery 发出请求时,BigQuery 会将 Etag 值与 API 返回的 ETag 值进行比较,并根据两个 ETag 值是否匹配做出响应。您可以通过下列方式使用 ETag 避免冗余列表调用:

  • 如果您只想在值已更改时返回列表值,请执行以下操作:

    如果您只想在值已更改时返回列表值页面,则可以通过 HTTP“if-none-match”标头使用先前存储的 ETag 进行列表调用。如果您提供的 ETag 与服务器上的 ETag 不匹配,BigQuery 将返回一页新列表值。如果两个 ETag 匹配,则 BigQuery 返回 HTTP 304“Not Modified”结果,而不返回任何值。例如,用户可能会定期在一个网页中填写信息,该信息存储在 BigQuery 中。通过使用 if-none-match 标头和 ETag,可以避免在未更改数据的情况下对 BigQuery 进行冗余列表调用。

  • 如果您只想在未更改值时返回列表值,请执行以下操作:

    如果您只想在值未更改时返回列表值页面,可以使用 HTTP“if-match”标头。如果结果未更改,则 BigQuery 会匹配 ETag 值并返回结果页面;如果该页面已更改,则返回 412“Precondition Failed”结果。

注意:尽管 ETag 是避免进行冗余列表调用的好方法,但您也可以将此方法用于识别任何对象是否已更改。例如,您可以针对特定表执行 Get 请求,并使用 ETag 来确认在返回完整响应前该表是否已更改。
此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

此网页
需要帮助?请访问我们的支持页面