Membaca data dengan BigQuery API menggunakan penomoran halaman

Dokumen ini menjelaskan cara membaca data tabel dan hasil kueri dengan BigQuery API menggunakan penomoran halaman.

Menelusuri hasil menggunakan API

Semua metode *collection*.list menampilkan hasil yang diberi nomor halaman dalam keadaan tertentu. Properti maxResults membatasi jumlah hasil per halaman.

Metode Kriteria penomoran halaman Nilai maxResults default Nilai maxResults maksimum Nilai maxFieldValues maksimum
tabledata.list Menampilkan hasil yang diberi nomor halaman jika ukuran respons melebihi 10 MB1 data atau lebih dari maxResults baris. Tak terbatas Tidak terbatas Tak terbatas
Semua metode *collection*.list lainnya Menampilkan hasil yang diberi nomor halaman jika respons memiliki lebih dari maxResults baris dan juga kurang dari batas maksimum. 10.000 Tak terbatas 300.000

Jika hasilnya lebih besar dari batas byte atau kolom, hasilnya akan dipangkas agar sesuai dengan batas. Jika satu baris lebih besar dari batas byte atau kolom, tabledata.list dapat menampilkan hingga 100 MB data1, yang sesuai dengan batas ukuran baris maksimum untuk kueri hasil pengujian tersebut. Tidak ada ukuran minimum per halaman, dan beberapa halaman mungkin menampilkan lebih banyak baris daripada yang lain.

1Ukuran baris merupakan perkiraan, karena ukurannya didasarkan pada representasi internal dari data baris. Batas ukuran baris maksimum diterapkan selama tahap tertentu dari eksekusi tugas kueri.

jobs.getQueryResults dapat menampilkan 20 MB data kecuali jika secara eksplisit diminta lebih banyak melalui dukungan.

Halaman adalah subbagian dari jumlah total baris. Jika hasil Anda lebih dari satu halaman data, data hasil tersebut akan memiliki properti pageToken. Untuk mengambil halaman hasil berikutnya, lakukan panggilan list lain dan sertakan nilai token sebagai parameter URL bernama pageToken.

Metode tabledata.list, yang digunakan untuk menelusuri halaman data tabel, menggunakan nilai offset baris atau token halaman. Lihat Menjelajahi data tabel untuk mengetahui informasinya.

Melakukan iterasi melalui hasil library klien

Library klien cloud menangani detail level rendah penomoran halaman API dan memberikan pengalaman yang lebih mirip iterator sehingga menyederhanakan interaksi dengan elemen individual dalam respons halaman.

Contoh berikut menunjukkan penomoran halaman melalui data tabel BigQuery.

C#

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan C# di panduan memulai BigQuery menggunakan library klien. Untuk mengetahui informasi selengkapnya, lihat Dokumentasi referensi BigQuery C# API.

Untuk melakukan autentikasi ke BigQuery, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk library klien.


using Google.Api.Gax;
using Google.Apis.Bigquery.v2.Data;
using Google.Cloud.BigQuery.V2;
using System;
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

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Java di Panduan memulai BigQuery menggunakan library klien. Untuk mengetahui informasi selengkapnya, lihat Dokumentasi referensi BigQuery Java API.

Untuk melakukan autentikasi ke BigQuery, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk library klien.

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQuery.TableDataListOption;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.TableId;
import com.google.cloud.bigquery.TableResult;

// Sample to directly browse a table with optional paging
public class BrowseTable {

  public static void runBrowseTable() {
    // TODO(developer): Replace these variables before running the sample.
    String table = "MY_TABLE_NAME";
    String dataset = "MY_DATASET_NAME";
    browseTable(dataset, table);
  }

  public static void browseTable(String dataset, String table) {
    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();

      // Identify the table itself
      TableId tableId = TableId.of(dataset, table);

      // Page over 100 records. If you don't need pagination, remove the pageSize parameter.
      TableResult result = bigquery.listTableData(tableId, TableDataListOption.pageSize(100));

      // Print the records
      result
          .iterateAll()
          .forEach(
              row -> {
                row.forEach(fieldValue -> System.out.print(fieldValue.toString() + ", "));
                System.out.println();
              });

      System.out.println("Query ran successfully");
    } catch (BigQueryException e) {
      System.out.println("Query failed to run \n" + e.toString());
    }
  }
}

Go

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Go di Panduan memulai BigQuery menggunakan library klien. Untuk mengetahui informasi selengkapnya, lihat Dokumentasi referensi BigQuery Go API.

Untuk melakukan autentikasi ke BigQuery, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk library klien.

Library Klien Cloud untuk Go akan melakukan penomoran halaman secara otomatis secara default, sehingga Anda tidak perlu menerapkan penomoran halaman sendiri, misalnya:

import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/bigquery"
	"google.golang.org/api/iterator"
)

// browseTable demonstrates reading data from a BigQuery table directly without the use of a query.
// For large tables, we also recommend the BigQuery Storage API.
func browseTable(w io.Writer, 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()

	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.Fprintln(w, row)
	}
	return nil
}

Node.js

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Node.js di Panduan memulai BigQuery menggunakan library klien. Untuk mengetahui informasi selengkapnya, lihat Dokumentasi referensi BigQuery Node.js API.

Untuk melakukan autentikasi ke BigQuery, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk library klien.

Library Klien Cloud untuk Node.js akan diberi nomor halaman secara otomatis secara default, sehingga Anda tidak perlu menerapkan penomoran halaman sendiri, misalnya:

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

async function browseTable() {
  // Retrieve a table's rows using manual pagination.

  /**
   * TODO(developer): Uncomment the following lines before running the sample.
   */
  // const datasetId = 'my_dataset'; // Existing dataset
  // const tableId = 'my_table'; // Table to create

  const query = `SELECT name, SUM(number) as total_people
    FROM \`bigquery-public-data.usa_names.usa_1910_2013\`
    GROUP BY name
    ORDER BY total_people
    DESC LIMIT 100`;

  // Create table reference.
  const dataset = bigquery.dataset(datasetId);
  const destinationTable = dataset.table(tableId);

  // For all options, see https://cloud.google.com/bigquery/docs/reference/rest/v2/Job#jobconfigurationquery
  const queryOptions = {
    query: query,
    destination: destinationTable,
  };

  // Run the query as a job
  const [job] = await bigquery.createQueryJob(queryOptions);

  // For all options, see https://cloud.google.com/bigquery/docs/reference/v2/jobs/getQueryResults
  const queryResultsOptions = {
    // Retrieve zero resulting rows.
    maxResults: 0,
  };

  // Wait for the job to finish.
  await job.getQueryResults(queryResultsOptions);

  function manualPaginationCallback(err, rows, nextQuery) {
    rows.forEach(row => {
      console.log(`name: ${row.name}, ${row.total_people} total people`);
    });

    if (nextQuery) {
      // More results exist.
      destinationTable.getRows(nextQuery, manualPaginationCallback);
    }
  }

  // For all options, see https://cloud.google.com/bigquery/docs/reference/v2/tabledata/list
  const getRowsOptions = {
    autoPaginate: false,
    maxResults: 20,
  };

  // Retrieve all rows.
  destinationTable.getRows(getRowsOptions, manualPaginationCallback);
}
browseTable();

PHP

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan PHP di Panduan memulai BigQuery menggunakan library klien. Untuk mengetahui informasi selengkapnya, lihat Dokumentasi referensi BigQuery PHP API.

Untuk melakukan autentikasi ke BigQuery, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk library klien.

Penomoran halaman terjadi secara otomatis di Library Klien Cloud untuk PHP menggunakan fungsi generator rows, yang mengambil halaman hasil berikutnya selama iterasi.

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

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Python di Panduan memulai BigQuery menggunakan library klien. Untuk mengetahui informasi selengkapnya, lihat Dokumentasi referensi BigQuery Python API.

Untuk melakukan autentikasi ke BigQuery, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk library klien.

Library Klien Cloud untuk Python akan melakukan penomoran halaman secara otomatis secara default, sehingga Anda tidak perlu menerapkan penomoran halaman sendiri, misalnya:


from google.cloud import bigquery

# Construct a BigQuery client object.
client = bigquery.Client()

# TODO(developer): Set table_id to the ID of the table to browse data rows.
# table_id = "your-project.your_dataset.your_table_name"

# Download all rows from a table.
rows_iter = client.list_rows(table_id)  # Make an API request.

# Iterate over rows to make the API requests to fetch row data.
rows = list(rows_iter)
print("Downloaded {} rows from table {}".format(len(rows), table_id))

# Download at most 10 rows.
rows_iter = client.list_rows(table_id, max_results=10)
rows = list(rows_iter)
print("Downloaded {} rows from table {}".format(len(rows), table_id))

# Specify selected fields to limit the results to certain columns.
table = client.get_table(table_id)  # Make an API request.
fields = table.schema[:2]  # First two columns.
rows_iter = client.list_rows(table_id, selected_fields=fields, max_results=10)
rows = list(rows_iter)
print("Selected {} columns from table {}.".format(len(rows_iter.schema), table_id))
print("Downloaded {} rows from table {}".format(len(rows), table_id))

# Print row data in tabular format.
rows = client.list_rows(table, max_results=10)
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

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Ruby di Panduan memulai BigQuery menggunakan library klien. Untuk mengetahui informasi selengkapnya, lihat Dokumentasi referensi BigQuery Ruby API.

Untuk melakukan autentikasi ke BigQuery, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk library klien.

Penomoran halaman dilakukan secara otomatis di Library Klien Cloud untuk Ruby menggunakan Table#data dan Data#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

Minta halaman arbitrer dan hindari panggilan daftar yang berlebihan

Jika Anda memundurkan halaman atau melompat ke halaman arbitrer menggunakan nilai pageToken yang di-cache, data di halaman Anda mungkin telah berubah sejak terakhir dilihat, tetapi tidak ada indikasi yang jelas bahwa datanya mungkin telah berubah. Untuk mengurangi hal ini, Anda dapat menggunakan properti etag.

Setiap metode collection.list (kecuali untuk Tabledata) menampilkan properti etag dalam hasil. Properti ini adalah hash hasil halaman yang dapat digunakan untuk memverifikasi apakah halaman telah berubah sejak permintaan terakhir. Ketika Anda membuat permintaan ke BigQuery berisi nilai ETag, BigQuery akan membandingkan nilai ETag dengan nilai ETag yang ditampilkan oleh API dan merespons berdasarkan apakah nilai ETag-nya cocok atau tidak. Anda dapat menggunakan ETag untuk menghindari panggilan daftar yang berlebihan seperti berikut ini:

  • Untuk menampilkan nilai daftar jika nilainya telah berubah.

    Jika Anda hanya ingin menampilkan halaman yang berisi nilai daftar jika nilainya telah berubah, Anda dapat membuat panggilan daftar dengan ETag yang sebelumnya disimpan menggunakanHeader HTTP "if-none-match". Jika ETag yang Anda berikan tidak sesuai dengan ETag di server, BigQuery akan menampilkan halaman nilai daftar baru. Jika ETag sesuai, BigQuery akan menampilkan kode status HTTP 304 Not Modified dan tanpa nilai. Contohnya adalah halaman web tempat pengguna dapat mengisi informasi yang disimpan di BigQuery secara berkala. Jika tidak ada perubahan pada data, Anda dapat menghindari membuat panggilan daftar yang berlebihan ke BigQuery dengan menggunakan header if-none-match dengan ETag.

  • Untuk menampilkan nilai daftar jika nilainya belum berubah.

    Jika Anda hanya ingin menampilkan halaman nilai daftar jika nilai daftar belum berubah, Anda dapat menggunakan header HTTP "if-match". BigQuery mencocokkan nilai ETag dan menampilkan halaman hasil jika hasilnya tidak berubah, atau menampilkan hasil "Prakondisi Gagal" 412 jika halaman telah berubah.

Catatan: Meskipun ETag adalah cara yang tepat untuk menghindari panggilan daftar yang berlebihan, Anda dapat menerapkan metode yang sama untuk mengidentifikasi apakah objek telah berubah. Misalnya, Anda dapat melakukan permintaan Get untuk tabel tertentu dan menggunakan ETag untuk menentukan apakah tabel telah berubah sebelum menampilkan respons penuh.

Menelusuri hasil kueri

Setiap kueri menulis ke tabel tujuan. Jika tidak ada tabel tujuan yang disediakan, BigQuery API akan otomatis mengisi properti tabel tujuan dengan referensi ke tabel anonim sementara.

API

Baca kolom jobs.config.query.destinationTable untuk menentukan tabel tempat hasil kueri ditulis. Panggil tabledata.list untuk membaca hasil kueri.

Java

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Java di Panduan memulai BigQuery menggunakan library klien. Untuk mengetahui informasi selengkapnya, lihat Dokumentasi referensi BigQuery Java API.

Untuk melakukan autentikasi ke BigQuery, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk library klien.

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.QueryJobConfiguration;
import com.google.cloud.bigquery.TableId;
import com.google.cloud.bigquery.TableResult;

// Sample to run query with pagination.
public class QueryPagination {

  public static void main(String[] args) {
    String datasetName = "MY_DATASET_NAME";
    String tableName = "MY_TABLE_NAME";
    String query =
        "SELECT name, SUM(number) as total_people"
            + " FROM `bigquery-public-data.usa_names.usa_1910_2013`"
            + " GROUP BY name"
            + " ORDER BY total_people DESC"
            + " LIMIT 100";
    queryPagination(datasetName, tableName, query);
  }

  public static void queryPagination(String datasetName, String tableName, 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();

      TableId tableId = TableId.of(datasetName, tableName);
      QueryJobConfiguration queryConfig =
          QueryJobConfiguration.newBuilder(query)
              // save results into a table.
              .setDestinationTable(tableId)
              .build();

      bigquery.query(queryConfig);

      TableResult results =
          bigquery.listTableData(tableId, BigQuery.TableDataListOption.pageSize(20));

      // First Page
      results
          .getValues()
          .forEach(row -> row.forEach(val -> System.out.printf("%s,\n", val.toString())));

      if (results.hasNextPage()) {
        // Next Page
        results
            .getNextPage()
            .getValues()
            .forEach(row -> row.forEach(val -> System.out.printf("%s,\n", val.toString())));
      }

      if (results.hasNextPage()) {
        // Remaining Pages
        results
            .getNextPage()
            .iterateAll()
            .forEach(row -> row.forEach(val -> System.out.printf("%s,\n", val.toString())));
      }

      System.out.println("Query pagination performed successfully.");
    } catch (BigQueryException | InterruptedException e) {
      System.out.println("Query not performed \n" + e.toString());
    }
  }
}

Node.js

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Node.js di Panduan memulai BigQuery menggunakan library klien. Untuk mengetahui informasi selengkapnya, lihat Dokumentasi referensi BigQuery Node.js API.

Untuk melakukan autentikasi ke BigQuery, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk library klien.

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

async function queryPagination() {
  // Run a query and get rows using automatic pagination.

  const query = `SELECT name, SUM(number) as total_people
  FROM \`bigquery-public-data.usa_names.usa_1910_2013\`
  GROUP BY name
  ORDER BY total_people DESC
  LIMIT 100`;

  // Run the query as a job.
  const [job] = await bigquery.createQueryJob(query);

  // Wait for job to complete and get rows.
  const [rows] = await job.getQueryResults();

  console.log('Query results:');
  rows.forEach(row => {
    console.log(`name: ${row.name}, ${row.total_people} total people`);
  });
}
queryPagination();

Python

Metode QueryJob.result menampilkan iterable hasil kueri. Sebagai alternatif,

  1. Baca properti QueryJob.destination. Jika tidak dikonfigurasi, properti ini akan ditetapkan oleh API ke referensi ke tabel anonim sementara.
  2. Dapatkan skema tabel dengan metode Client.get_table.
  3. Buat iterable di semua baris dalam tabel tujuan dengan metode Client.list_rows.

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Python di Panduan memulai BigQuery menggunakan library klien. Untuk mengetahui informasi selengkapnya, lihat Dokumentasi referensi BigQuery Python API.

Untuk melakukan autentikasi ke BigQuery, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk library klien.


from google.cloud import bigquery

# Construct a BigQuery client object.
client = bigquery.Client()

query = """
    SELECT name, SUM(number) as total_people
    FROM `bigquery-public-data.usa_names.usa_1910_2013`
    GROUP BY name
    ORDER BY total_people DESC
"""
query_job = client.query(query)  # Make an API request.
query_job.result()  # Wait for the query to complete.

# Get the destination table for the query results.
#
# All queries write to a destination table. If a destination table is not
# specified, the BigQuery populates it with a reference to a temporary
# anonymous table after the query completes.
destination = query_job.destination

# Get the schema (and other properties) for the destination table.
#
# A schema is useful for converting from BigQuery types to Python types.
destination = client.get_table(destination)

# Download rows.
#
# The client library automatically handles pagination.
print("The query data:")
rows = client.list_rows(destination, max_results=20)
for row in rows:
    print("name={}, count={}".format(row["name"], row["total_people"]))