将表数据导出到 Cloud Storage

本页面介绍如何将 BigQuery 表中的数据导出或提取到 Cloud Storage。

将数据加载到 BigQuery 中后,您可以使用多种格式导出数据。BigQuery 最多可以将 1 GB 的数据导出到单个文件。如果您要导出 1 GB 以上的数据,则必须将数据导出到多个文件。将数据导出到多个文件时,文件的大小会有所不同。

您可以使用 Dataflow 等服务从 BigQuery 读取数据,而不必手动导出数据。如需详细了解如何使用 Dataflow 对 BigQuery 执行读写操作,请参阅 Apache Beam 文档中的 BigQuery I/O

您还可以使用 EXPORT DATA 语句导出查询结果。 您可以使用 EXPORT DATA OPTIONS 将视图导出到 Cloud Storage。

导出限制

从 BigQuery 导出数据时,请注意以下事项:

  • 您不能将表数据导出到本地文件、Google 表格或 Google 云端硬盘。系统唯一支持的导出位置是 Cloud Storage。如需了解如何保存查询结果,请参阅下载和保存查询结果
  • 您最多可以将 1 GB 的表数据导出到单个文件中。如果要导出 1 GB 以上的数据,请使用通配符将数据导出到多个文件。将数据导出到多个文件时,各个文件的大小会有所不同。如需限制导出文件的大小,您可以对数据进行分区并导出每个分区。
  • 无法保证使用 EXPORT DATA 语句时生成的文件大小。
  • 导出作业生成的文件数量可能会有所不同。
  • 您不能使用 CSV 格式导出嵌套数据和重复数据。Avro、JSON 和 Parquet 导出格式支持嵌套和重复数据。
  • 使用 JSON 格式导出数据时,INT64(整数)数据类型会编码为 JSON 字符串,以便在其他系统读取数据时保留 64 位精度。
  • 您无法在一个导出作业中导出多个表中的数据。
  • 使用 Google Cloud 控制台导出数据时,您不能选择 GZIP 以外的压缩类型。
  • 我们建议您不要将数据导出到已启用保留政策的 Cloud Storage 存储分区。BigQuery 可能会尝试将文件写入存储桶,如果存储桶的保留政策阻止覆盖文件,这些重试可能会失败。如果您需要将数据导出到具有保留政策的 Cloud Storage 存储桶,请先停用该政策,然后再开始导出。
  • 以 JSON 格式导出表时,系统会使用 Unicode 表示法 \uNNNN 转换符号 <>&,其中 N 是十六进制数字。例如,profit&loss 变为 profit\u0026loss。完成此 Unicode 转换是为了避免安全漏洞。
  • 除非您使用 EXPORT DATA 语句并在 query_statement 中指定 ORDER BY 子句,否则无法保证导出表数据的顺序。
  • BigQuery 不支持 Cloud Storage 资源路径在初始双斜杠之后添加多个连续斜杠。Cloud Storage 对象名称可包含多个连续斜杠(“/”)字符。但是,BigQuery 会将多个连续斜杠转换为单个斜杠。例如,以下资源路径在 Cloud Storage 中有效,但在 BigQuery 中无效:gs://bucket/my//object//name
  • 在导出作业运行期间加载到 BigQuery 的所有新数据都不会包含在该导出作业中。您必须创建新的导出作业才能导出新数据。

准备工作

授予为用户提供执行本文档中的每个任务所需权限的 Identity and Access Management (IAM) 角色。

所需权限

如需执行本文档中的任务,您需要以下权限。

从 BigQuery 表导出数据的权限

如需从 BigQuery 表导出数据,您需要 bigquery.tables.export IAM 权限。

以下每个预定义 IAM 角色都具有 bigquery.tables.export 权限:

  • roles/bigquery.dataViewer
  • roles/bigquery.dataOwner
  • roles/bigquery.dataEditor
  • roles/bigquery.admin

运行导出作业的权限

如需运行导出作业,您需要拥有 bigquery.jobs.create IAM 权限。

以下每个预定义的 IAM 角色均包含运行导出作业所需的权限:

  • roles/bigquery.user
  • roles/bigquery.jobUser
  • roles/bigquery.admin

将数据写入 Cloud Storage 存储桶的权限

如需将数据写入现有 Cloud Storage 存储桶,您需要拥有以下 IAM 权限:

  • storage.objects.create
  • storage.objects.delete

以下每个预定义的 IAM 角色均包含将数据写入现有 Cloud Storage 存储桶所需的权限:

  • roles/storage.objectAdmin
  • roles/storage.admin

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

位置注意事项

共置 Cloud Storage 存储桶,以导出数据:
  • 如果您的 BigQuery 数据集位于 EU 多区域,则包含您所导出的数据的 Cloud Storage 存储桶必须位于同一多区域或该多区域内的位置。例如,如果您的 BigQuery 数据集位于 EU 多区域,则 Cloud Storage 存储桶可以位于欧盟内的 europe-west1 比利时区域。

    如果您的数据集位于 US 多区域,则您可以将数据导出到任何位置的 Cloud Storage 存储桶。

  • 如果您的数据集位于某个区域,则 Cloud Storage 存储桶必须位于同一区域。例如,如果您的数据集位于 asia-northeast1 东京区域,则您的 Cloud Storage 存储桶不能位于 ASIA 多区域。
制定数据管理计划:
  • 如果您选择区域存储资源(如 BigQuery 数据集或 Cloud Storage 存储桶),请制定按地理位置管理数据的计划。

如需详细了解 Cloud Storage 位置,请参阅 Cloud Storage 文档中的存储桶位置

在不同位置之间移动 BigQuery 数据

您无法在创建数据集后更改其位置,但可以创建数据集的副本。您无法将数据集从一个位置移动到另一个位置,但可以手动移动(重新创建)数据集

导出格式和压缩类型

对于导出数据,BigQuery 支持以下数据格式和压缩类型。

数据格式 支持的压缩类型 详细信息
CSV GZIP

您可以使用 --field_delimiter bq 命令行工具标志或 configuration.extract.fieldDelimiter 提取作业属性控制导出数据中的 CSV 分隔符。

不支持嵌套数据和重复数据。

JSON GZIP 支持嵌套和重复数据。
Avro DEFLATE、SNAPPY

Avro 导出格式不支持 GZIP 压缩类型。

支持嵌套和重复数据。请参阅 Avro 导出详细信息

Parquet SNAPPY、GZIP、ZSTD

支持嵌套和重复数据。请参阅 Parquet 导出详细信息

导出数据

您可以通过以下方式导出表数据:

  • 使用 Google Cloud 控制台
  • 在 bq 命令行工具中使用 bq extract 命令。
  • 使用 API 或客户端库提交 extract 作业

导出表数据

如需从 BigQuery 表导出数据,请执行以下操作:

控制台

  1. 在 Google Cloud 控制台中打开 BigQuery 页面。

    转到 BigQuery 页面

  2. 探索器面板中,展开您的项目和数据集,然后选择表。

  3. 在详情面板中,点击导出,然后选择导出到 Cloud Storage

  4. 将表导出到 Google Cloud Storage 对话框中,执行以下操作:

    • 对于选择 Google Cloud Storage 的位置,请浏览要导出数据的存储桶、文件夹或文件。
    • 导出格式中,选择导出数据的格式:CSV、JSON(以换行符分隔)、Avro 或 Parquet。
    • 压缩部分,选择压缩格式或选择 None 表示不压缩。
    • 点击导出以导出表。google3/googledata/devsite/site-cloud/en/bigquery/docs/introduction-sql.md 如需检查作业进度,请在导航窗格顶部附近查找导出作业的作业历史记录

如需将视图导出到 Cloud Storage,请使用 EXPORT DATA OPTIONS 语句

SQL

使用 EXPORT DATA 语句。以下示例从名为 mydataset.table1 的表中导出选定的字段。

  1. 在 Google Cloud 控制台中,转到 BigQuery 页面。

    转到 BigQuery

  2. 在查询编辑器中,输入以下语句:

    EXPORT DATA
      OPTIONS (
        uri = 'gs://bucket/folder/*.csv',
        format = 'CSV',
        overwrite = true,
        header = true,
        field_delimiter = ';')
    AS (
      SELECT field1, field2
      FROM mydataset.table1
      ORDER BY field1
    );

  3. 点击 运行

如需详细了解如何运行查询,请参阅运行交互式查询

bq

结合使用 bq extract--destination_format 标志。

(可选)提供 --location 标志并将其值设置为您的位置

其他可选标志包括:

  • --compression:此标志表示导出文件使用的压缩类型。
  • --field_delimiter:此标志是在使用 CSV 导出格式的输出文件中用于表示各列之间边界的字符。\ttab 都可用来表示制表符分隔符。
  • --print_header:如果指定了此标志,则系统在输出带有标题的格式(如 CSV)时,就会输出标题行。
bq extract --location=location \
--destination_format format \
--compression compression_type \
--field_delimiter delimiter \
--print_header=boolean \
project_id:dataset.table \
gs://bucket/filename.ext

其中:

  • location 是位置的名称。--location 是可选标志。例如,如果您在东京区域使用 BigQuery,可将该标志的值设置为 asia-northeast1。您可以使用 .bigqueryrc 文件设置位置的默认值。
  • format 是导出数据的格式:CSVNEWLINE_DELIMITED_JSONAVROPARQUET
  • compression_type 是数据格式支持的压缩类型。请参阅导出格式和压缩类型
  • delimiter 是用于表示 CSV 导出文件中各列之间边界的字符。您可以使用 \ttab 表示制表符。
  • booleantruefalse。设置为 true 时,如果数据格式支持标题,则标题行将输出到导出数据。默认值为 true
  • project_id 是项目 ID。
  • dataset 是源数据集的名称。
  • table 是您要导出的表。如果使用分区修饰器,则必须使用英文单引号将表路径括起或转义 $ 字符。
  • bucket 是要向其中导出数据的 Cloud Storage 存储桶的名称。BigQuery 数据集和 Cloud Storage 存储桶必须位于同一位置
  • filename.ext 是导出数据文件的名称和扩展名。您可以使用通配符导出到多个文件。

示例:

例如,以下命令会将 mydataset.mytable 导出到名为 myfile.csv 的 gzip 压缩文件中。myfile.csv 存储在名为 example-bucket 的 Cloud Storage 存储桶中。

bq extract \
--compression GZIP \
'mydataset.mytable' \
gs://example-bucket/myfile.csv

默认目标格式是 CSV。要导出为 JSON 或 Avro 格式,请使用 destination_format 标志并将其设置为 NEWLINE_DELIMITED_JSONAVRO。例如:

bq extract \
--destination_format NEWLINE_DELIMITED_JSON \
'mydataset.mytable' \
gs://example-bucket/myfile.json

以下命令会将 mydataset.mytable 导出到使用 Snappy 压缩的 Avro 文件中。该文件的名称为 myfile.avromyfile.avro 将导出到名为 example-bucket 的 Cloud Storage 存储桶。

bq extract \
--destination_format AVRO \
--compression SNAPPY \
'mydataset.mytable' \
gs://example-bucket/myfile.avro

以下命令会将 mydataset.my_partitioned_table 的单个分区导出到 Cloud Storage 中的 CSV 文件:

bq extract \
--destination_format CSV \
'mydataset.my_partitioned_table$0' \
gs://example-bucket/single_partition.csv

API

如需导出数据,请创建一个 extract 作业,并填充作业配置。

(可选)在作业资源jobReference 部分的 location 属性中指定您的位置。

  1. 创建一个 extract 作业,将其指向 BigQuery 源数据和 Cloud Storage 目标。

  2. 使用包含项目 ID、数据集 ID 和表 ID 的 sourceTable 配置对象,来指定源表。

  3. destination URI(s) 属性必须是完全限定的,格式为 gs://bucket/filename.ext。 每个 URI 都可以包含一个“*”通配符,此通配符必须位于存储桶名称之后。

  4. 通过设置 configuration.extract.destinationFormat 属性来指定数据格式。例如,要导出 JSON 文件,可将此属性设置为 NEWLINE_DELIMITED_JSON 值。

  5. 如需检查作业状态,请使用初始请求返回的作业 ID 来调用 jobs.get(job_id)

    • 如果 status.state = DONE,则表示作业已成功完成。
    • 如果出现 status.errorResult 属性,则表示请求失败,并且该对象将包含描述问题的相关信息。
    • 如果未出现 status.errorResult,则表示作业已成功完成,但可能存在一些非严重错误。返回的作业对象的 status.errors 属性中列出了非严重错误。

API 说明

  • 在调用 jobs.insert 来创建作业时,最佳做法是生成唯一 ID,并将其作为 jobReference.jobId 传递。此方法比较不会受到网络故障的影响,因为客户端可以对已知的作业 ID 进行轮询或重试。

  • 对指定的作业 ID 调用 jobs.insert 具有幂等性,即您可以对同一作业 ID 进行无限次重试,但最多只会有一个成功操作。

C#

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

如需向 BigQuery 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证


using Google.Cloud.BigQuery.V2;
using System;

public class BigQueryExtractTable
{
    public void ExtractTable(
        string projectId = "your-project-id",
        string bucketName = "your-bucket-name")
    {
        BigQueryClient client = BigQueryClient.Create(projectId);
        // Define a destination URI. Use a single wildcard URI if you think
        // your exported data will be larger than the 1 GB maximum value.
        string destinationUri = $"gs://{bucketName}/shakespeare-*.csv";
        BigQueryJob job = client.CreateExtractJob(
            projectId: "bigquery-public-data",
            datasetId: "samples",
            tableId: "shakespeare",
            destinationUri: destinationUri
        );
        job = job.PollUntilCompleted().ThrowOnAnyError();  // Waits for the job to complete.
        Console.Write($"Exported table to {destinationUri}.");
    }
}

Go

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

如需向 BigQuery 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证

import (
	"context"
	"fmt"

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

// exportTableAsCompressedCSV demonstrates using an export job to
// write the contents of a table into Cloud Storage as CSV.
func exportTableAsCSV(projectID, gcsURI string) error {
	// projectID := "my-project-id"
	// gcsUri := "gs://mybucket/shakespeare.csv"
	ctx := context.Background()
	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %v", err)
	}
	defer client.Close()

	srcProject := "bigquery-public-data"
	srcDataset := "samples"
	srcTable := "shakespeare"

	gcsRef := bigquery.NewGCSReference(gcsURI)
	gcsRef.FieldDelimiter = ","

	extractor := client.DatasetInProject(srcProject, srcDataset).Table(srcTable).ExtractorTo(gcsRef)
	extractor.DisableHeader = true
	// You can choose to run the job in a specific location for more complex data locality scenarios.
	// Ex: In this example, source dataset and GCS bucket are in the US.
	extractor.Location = "US"

	job, err := extractor.Run(ctx)
	if err != nil {
		return err
	}
	status, err := job.Wait(ctx)
	if err != nil {
		return err
	}
	if err := status.Err(); err != nil {
		return err
	}
	return nil
}

Java

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

如需向 BigQuery 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证

import com.google.cloud.RetryOption;
import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.Job;
import com.google.cloud.bigquery.Table;
import com.google.cloud.bigquery.TableId;
import org.threeten.bp.Duration;

public class ExtractTableToCsv {

  public static void runExtractTableToCsv() {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "bigquery-public-data";
    String datasetName = "samples";
    String tableName = "shakespeare";
    String bucketName = "my-bucket";
    String destinationUri = "gs://" + bucketName + "/path/to/file";
    // For more information on export formats available see:
    // https://cloud.google.com/bigquery/docs/exporting-data#export_formats_and_compression_types
    // For more information on Job see:
    // https://googleapis.dev/java/google-cloud-clients/latest/index.html?com/google/cloud/bigquery/package-summary.html

    String dataFormat = "CSV";
    extractTableToCsv(projectId, datasetName, tableName, destinationUri, dataFormat);
  }

  // Exports datasetName:tableName to destinationUri as raw CSV
  public static void extractTableToCsv(
      String projectId,
      String datasetName,
      String tableName,
      String destinationUri,
      String dataFormat) {
    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(projectId, datasetName, tableName);
      Table table = bigquery.getTable(tableId);

      Job job = table.extract(dataFormat, destinationUri);

      // Blocks until this job completes its execution, either failing or succeeding.
      Job completedJob =
          job.waitFor(
              RetryOption.initialRetryDelay(Duration.ofSeconds(1)),
              RetryOption.totalTimeout(Duration.ofMinutes(3)));
      if (completedJob == null) {
        System.out.println("Job not executed since it no longer exists.");
        return;
      } else if (completedJob.getStatus().getError() != null) {
        System.out.println(
            "BigQuery was unable to extract due to an error: \n" + job.getStatus().getError());
        return;
      }
      System.out.println(
          "Table export successful. Check in GCS bucket for the " + dataFormat + " file.");
    } catch (BigQueryException | InterruptedException e) {
      System.out.println("Table extraction job was interrupted. \n" + e.toString());
    }
  }
}

Node.js

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

如需向 BigQuery 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证

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

const bigquery = new BigQuery();
const storage = new Storage();

async function extractTableToGCS() {
  // Exports my_dataset:my_table to gcs://my-bucket/my-file as raw CSV.

  /**
   * TODO(developer): Uncomment the following lines before running the sample.
   */
  // const datasetId = "my_dataset";
  // const tableId = "my_table";
  // const bucketName = "my-bucket";
  // const filename = "file.csv";

  // Location must match that of the source table.
  const options = {
    location: 'US',
  };

  // Export data from the table into a Google Cloud Storage file
  const [job] = await bigquery
    .dataset(datasetId)
    .table(tableId)
    .extract(storage.bucket(bucketName).file(filename), options);

  console.log(`Job ${job.id} created.`);

  // Check the job's status for errors
  const errors = job.status.errors;
  if (errors && errors.length > 0) {
    throw errors;
  }
}

PHP

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

如需向 BigQuery 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证

use Google\Cloud\BigQuery\BigQueryClient;

/**
 * Extracts the given table as json to given GCS bucket.
 *
 * @param string $projectId The project Id of your Google Cloud Project.
 * @param string $datasetId The BigQuery dataset ID.
 * @param string $tableId The BigQuery table ID.
 * @param string $bucketName Bucket name in Google Cloud Storage
 */
function extract_table(
    string $projectId,
    string $datasetId,
    string $tableId,
    string $bucketName
): void {
    $bigQuery = new BigQueryClient([
      'projectId' => $projectId,
    ]);
    $dataset = $bigQuery->dataset($datasetId);
    $table = $dataset->table($tableId);
    $destinationUri = "gs://{$bucketName}/{$tableId}.json";
    // Define the format to use. If the format is not specified, 'CSV' will be used.
    $format = 'NEWLINE_DELIMITED_JSON';
    // Create the extract job
    $extractConfig = $table->extract($destinationUri)->destinationFormat($format);
    // Run the job
    $job = $table->runJob($extractConfig);  // Waits for the job to complete
    printf('Exported %s to %s' . PHP_EOL, $table->id(), $destinationUri);
}

Python

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

如需向 BigQuery 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证

# from google.cloud import bigquery
# client = bigquery.Client()
# bucket_name = 'my-bucket'
project = "bigquery-public-data"
dataset_id = "samples"
table_id = "shakespeare"

destination_uri = "gs://{}/{}".format(bucket_name, "shakespeare.csv")
dataset_ref = bigquery.DatasetReference(project, dataset_id)
table_ref = dataset_ref.table(table_id)

extract_job = client.extract_table(
    table_ref,
    destination_uri,
    # Location must match that of the source table.
    location="US",
)  # API request
extract_job.result()  # Waits for job to complete.

print(
    "Exported {}:{}.{} to {}".format(project, dataset_id, table_id, destination_uri)
)

Ruby

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

如需向 BigQuery 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证

require "google/cloud/bigquery"

def extract_table bucket_name = "my-bucket",
                  dataset_id  = "my_dataset_id",
                  table_id    = "my_table_id"
  bigquery = Google::Cloud::Bigquery.new
  dataset  = bigquery.dataset dataset_id
  table    = dataset.table    table_id

  # Define a destination URI. Use a single wildcard URI if you think
  # your exported data will be larger than the 1 GB maximum value.
  destination_uri = "gs://#{bucket_name}/output-*.csv"

  extract_job = table.extract_job destination_uri do |config|
    # Location must match that of the source table.
    config.location = "US"
  end
  extract_job.wait_until_done! # Waits for the job to complete

  puts "Exported #{table.id} to #{destination_uri}"
end

Avro 导出详情

BigQuery 通过以下方式表示 Avro 格式的数据:

  • 所生成的导出文件是 Avro 容器文件。
  • 每个 BigQuery 行均表示为一条 Avro 记录。嵌套数据由嵌套的 record 对象表示。
  • REQUIRED 字段表示为相应的 Avro 类型。例如,BigQuery INTEGER 类型会映射到 Avro LONG 类型。
  • NULLABLE 字段表示为相应类型的 Avro 并集和一个“null”。
  • REPEATED 字段表示为 Avro 数组。
  • TIMESTAMP 数据类型在提取作业和导出数据 SQL 中默认表示为 timestamp-micros 逻辑类型(用于注解 Avro LONG 类型)。(注意:您可以将 use_avro_logical_types=False 添加到 Export Data Options 来停用逻辑类型,以便在时间戳列中改用 string 类型,但在提取作业中,它始终使用 Avro 逻辑类型。)
  • 在 Export Data SQL 中,DATE 数据类型默认表示为 date 逻辑类型(它注释 Avro INT 类型),但默认情况下在提取作业中表示为 string 类型。(注意:您可以将 use_avro_logical_types=False 添加到 Export Data Options 以停用逻辑类型,或使用 --use_avro_logical_types=True 标志在提取作业中启用逻辑类型。)
  • 在 Export Data SQL 中,TIME 数据类型默认表示为 timestamp-micro 逻辑类型(它注释 Avro LONG 类型),但默认情况下在提取作业中表示为 string 类型。(注意:您可以将 use_avro_logical_types=False 添加到 Export Data Options 以停用逻辑类型,或使用 --use_avro_logical_types=True 标志在提取作业中启用逻辑类型。)
  • 在 Export Data SQL 中,DATETIME 数据类型默认表示为 Avro STRING 类型(具有自定义指定逻辑类型 datetime 的字符串类型),但在提取作业中表示为 string 类型。(注意:您可以将 use_avro_logical_types=False 添加到 Export Data Options 以停用逻辑类型,或使用 --use_avro_logical_types=True 标志在提取作业中启用逻辑类型。)
  • Avro 导出不支持 RANGE 类型

参数化 NUMERIC(P[, S])BIGNUMERIC(P[, S]) 数据类型会将其精度和标度类型参数转换为 Avro 十进制逻辑类型。

Avro 格式不能与 GZIP 压缩类型结合使用。要压缩 Avro 数据,请使用 bq 命令行工具或 API,并指定 Avro 数据支持的一种压缩类型(DEFLATESNAPPY)。

Parquet 导出详细信息

BigQuery 会将 GoogleSQL 数据类型转换为以下 Parquet 数据类型:

BigQuery 数据类型 Parquet 原初类型 Parquet 逻辑类型
整数 INT64 NONE
数字 FIXED_LEN_BYTE_ARRAY DECIMAL (precision = 38, scale = 9)
Numeric(P[, S]) FIXED_LEN_BYTE_ARRAY DECIMAL (precision = P, scale = S)
BigNumeric FIXED_LEN_BYTE_ARRAY DECIMAL (precision = 76, scale = 38)
BigNumeric(P[, S]) FIXED_LEN_BYTE_ARRAY DECIMAL (precision = P, scale = S)
浮点 FLOAT NONE
布尔值 BOOLEAN NONE
字符串 BYTE_ARRAY STRING (UTF8)
字节 BYTE_ARRAY NONE
日期 INT32 DATE
日期时间 INT64 TIMESTAMP (isAdjustedToUTC = false, unit = MICROS)
时间 INT64 TIME (isAdjustedToUTC = true, unit = MICROS)
时间戳 INT64 TIMESTAMP (isAdjustedToUTC = false, unit = MICROS)
地理位置 BYTE_ARRAY GEOGRAPHY (edges = spherical)

Parquet 架构将嵌套数据表示为一组,将重复记录表示为重复组。如需详细了解如何在 BigQuery 中使用嵌套和重复数据,请参阅指定嵌套和重复列

您可以对 DATETIME 类型使用以下解决方法:

  • 将文件加载到暂存表中。然后,使用 SQL 查询将字段转换为 DATETIME,并将结果保存到新表中。如需了解详情,请参阅更改列的数据类型
  • 在加载作业中使用 --schema 标志为表提供架构。将日期时间列定义为 col:DATETIME

GEOGRAPHY 逻辑类型由添加到导出文件的 GeoParquet 元数据表示。

将数据导出到一个或多个文件

destinationUris 属性指示 BigQuery 应将您的文件导出到的一个或多个位置和文件名。

BigQuery 支持在每个 URI 中使用单个通配符运算符 (*)。通配符可以出现在 URI 中的任何位置,但不能包含在存储桶的名称中。使用通配符运算符可指示 BigQuery 根据所提供的模式创建多个分片文件。通配符运算符会替换为数字(从 0 开始),并向左填充 12 位。例如,如果 URI 的文件名末尾处带有通配符,那么在创建文件时,第一个文件的名称末尾会附加 000000000000,第二个文件的名称末尾会附加 000000000001,依次类推。

下表描述了 destinationUris 属性的几种可能的选项:

destinationUris 选项
单个 URI

如果要导出的表数据未超过 1 GB,请使用单个 URI。最常见的使用情形就是采用这种方式,因为导出的数据通常都小于 1 GB 上限值。EXPORT DATA 语句不支持此选项;您必须使用单个通配符 URI。

属性定义

['gs://my-bucket/file-name.json']

创建

gs://my-bucket/file-name.json
单个通配符 URI

如果您认为导出的数据会超过 1 GB 上限值,请使用单个通配符 URI。BigQuery 会根据所提供的模式将数据分片到多个文件。各个导出文件的大小会有所不同。

如果在文件名以外的 URI 组成部分中使用通配符,请在导出数据之前确保不存在该路径组成部分。

属性定义

['gs://my-bucket/file-name-*.json']

创建

gs://my-bucket/file-name-000000000000.json
gs://my-bucket/file-name-000000000001.json
gs://my-bucket/file-name-000000000002.json
...

限制导出文件的大小

在一次导出中导出超过 1 GB 的数据时,您必须使用通配符将数据导出到多个文件,且文件的大小有所不同。如果您需要限制每个导出文件的大小上限,一种方法是随机对数据进行分区,然后将每个分区导出到文件中:

  1. 确定所需的分区数量,该数量等于数据总大小除以所选导出文件大小。例如,如果您有 8,000 MB 数据,并且您希望每个导出文件的大小约为 20 MB,则需要 400 个分区。
  2. 创建一个新表,该表按名为 export_id 的随机生成的新列进行分区和聚类。 以下示例展示了如何根据名为 source_table 的现有表创建新的 processed_table,需要 n 个分区才能达到所选文件大小:

    CREATE TABLE my_dataset.processed_table
    PARTITION BY RANGE_BUCKET(export_id, GENERATE_ARRAY(0, n, 1))
    CLUSTER BY export_id
    AS (
      SELECT *, CAST(FLOOR(n*RAND()) AS INT64) AS export_id
      FROM my_dataset.source_table
    );
  3. 对于 0 到 n-1 之间的每个整数 i,对以下查询运行 EXPORT DATA 语句:

    SELECT * EXCEPT(export_id)
    FROM my_dataset.processed_table
    WHERE export_id = i;

提取压缩表

Go

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

如需向 BigQuery 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证

import (
	"context"
	"fmt"

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

// exportTableAsCompressedCSV demonstrates using an export job to
// write the contents of a table into Cloud Storage as compressed CSV.
func exportTableAsCompressedCSV(projectID, gcsURI string) error {
	// projectID := "my-project-id"
	// gcsURI := "gs://mybucket/shakespeare.csv"
	ctx := context.Background()
	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %w", err)
	}
	defer client.Close()

	srcProject := "bigquery-public-data"
	srcDataset := "samples"
	srcTable := "shakespeare"

	gcsRef := bigquery.NewGCSReference(gcsURI)
	gcsRef.Compression = bigquery.Gzip

	extractor := client.DatasetInProject(srcProject, srcDataset).Table(srcTable).ExtractorTo(gcsRef)
	extractor.DisableHeader = true
	// You can choose to run the job in a specific location for more complex data locality scenarios.
	// Ex: In this example, source dataset and GCS bucket are in the US.
	extractor.Location = "US"

	job, err := extractor.Run(ctx)
	if err != nil {
		return err
	}
	status, err := job.Wait(ctx)
	if err != nil {
		return err
	}
	if err := status.Err(); err != nil {
		return err
	}
	return nil
}

Java

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

如需向 BigQuery 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.ExtractJobConfiguration;
import com.google.cloud.bigquery.Job;
import com.google.cloud.bigquery.JobInfo;
import com.google.cloud.bigquery.TableId;

// Sample to extract a compressed table
public class ExtractTableCompressed {

  public static void main(String[] args) {
    // TODO(developer): Replace these variables before running the sample.
    String projectName = "MY_PROJECT_NAME";
    String datasetName = "MY_DATASET_NAME";
    String tableName = "MY_TABLE_NAME";
    String bucketName = "MY-BUCKET-NAME";
    String destinationUri = "gs://" + bucketName + "/path/to/file";
    // For more information on export formats available see:
    // https://cloud.google.com/bigquery/docs/exporting-data#export_formats_and_compression_types
    String compressed = "gzip";
    // For more information on Job see:
    // https://googleapis.dev/java/google-cloud-clients/latest/index.html?com/google/cloud/bigquery/package-summary.html
    String dataFormat = "CSV";

    extractTableCompressed(
        projectName, datasetName, tableName, destinationUri, dataFormat, compressed);
  }

  public static void extractTableCompressed(
      String projectName,
      String datasetName,
      String tableName,
      String destinationUri,
      String dataFormat,
      String compressed) {
    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(projectName, datasetName, tableName);

      ExtractJobConfiguration extractConfig =
          ExtractJobConfiguration.newBuilder(tableId, destinationUri)
              .setCompression(compressed)
              .setFormat(dataFormat)
              .build();

      Job job = bigquery.create(JobInfo.of(extractConfig));

      // Blocks until this job completes its execution, either failing or succeeding.
      Job completedJob = job.waitFor();
      if (completedJob == null) {
        System.out.println("Job not executed since it no longer exists.");
        return;
      } else if (completedJob.getStatus().getError() != null) {
        System.out.println(
            "BigQuery was unable to extract due to an error: \n" + job.getStatus().getError());
        return;
      }
      System.out.println("Table extract compressed successful");
    } catch (BigQueryException | InterruptedException e) {
      System.out.println("Table extraction job was interrupted. \n" + e.toString());
    }
  }
}

Node.js

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

如需向 BigQuery 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证

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

const bigquery = new BigQuery();
const storage = new Storage();

async function extractTableCompressed() {
  // Exports my_dataset:my_table to gcs://my-bucket/my-file as a compressed file.

  /**
   * TODO(developer): Uncomment the following lines before running the sample.
   */
  // const datasetId = "my_dataset";
  // const tableId = "my_table";
  // const bucketName = "my-bucket";
  // const filename = "file.csv";

  // Location must match that of the source table.
  const options = {
    location: 'US',
    gzip: true,
  };

  // Export data from the table into a Google Cloud Storage file
  const [job] = await bigquery
    .dataset(datasetId)
    .table(tableId)
    .extract(storage.bucket(bucketName).file(filename), options);

  console.log(`Job ${job.id} created.`);

  // Check the job's status for errors
  const errors = job.status.errors;
  if (errors && errors.length > 0) {
    throw errors;
  }
}

Python

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

如需向 BigQuery 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证

# from google.cloud import bigquery
# client = bigquery.Client()
# bucket_name = 'my-bucket'

destination_uri = "gs://{}/{}".format(bucket_name, "shakespeare.csv.gz")
dataset_ref = bigquery.DatasetReference(project, dataset_id)
table_ref = dataset_ref.table("shakespeare")
job_config = bigquery.job.ExtractJobConfig()
job_config.compression = bigquery.Compression.GZIP

extract_job = client.extract_table(
    table_ref,
    destination_uri,
    # Location must match that of the source table.
    location="US",
    job_config=job_config,
)  # API request
extract_job.result()  # Waits for job to complete.

导出表元数据

如需从 BigLake 托管式表中导出表元数据,请使用以下 SQL 语句:

EXPORT TABLE METADATA FROM `[[PROJECT_NAME.]DATASET_NAME.]TABLE_NAME`;

替换以下内容:

  • PROJECT_NAME:表所属项目的名称。该值默认为运行此查询的项目。
  • DATASET_NAME:表所属数据集的名称。
  • TABLE_NAME:表的名称。

导出的元数据位于 STORAGE_URI/metadata 文件夹中,其中 STORAGE_URI 是在选项中设置的表的存储位置。

用例示例

以下示例展示了如何将数据导出到 Cloud Storage。

假设您要将数据从端点日志连续流式传输到 Cloud Storage。每日快照会被导出到 Cloud Storage 以进行备份和归档。最佳选择是使用提取作业,但需遵循某些配额限制要求。

使用 API客户端库提交提取作业,并传入唯一 ID 作为 jobReference.jobId。提取作业是异步完成的。使用用于创建作业的唯一作业 ID 检查作业状态。如果 status.statusDONE,则表示作业已成功完成。如果存在 status.errorResult,则表示作业失败,需要重试。

批量数据处理

假设系统使用一个夜间批量作业在固定的截止时间之前完成数据加载。此加载作业完成后,系统将使用查询将具有统计信息的表具体化,如上一部分所述。系统会检索此表中的数据并将其编译为 PDF 报告,然后将其发送到监管机构。

由于需要读取的数据量很小,因此请使用 tabledata.list API 以 JSON 字典格式检索表中的所有行。如果具有多页数据,则结果会设置 pageToken 属性。如需检索下一页结果,请再次调用 tabledata.list,并提供标记值作为 pageToken 参数。如果 API 调用失败并显示 5xx 错误,请使用指数退避算法重试。大多数 4xx 错误无法重试。为更好地分离 BigQuery 导出和报告生成,结果应永久保存到磁盘。

配额政策

如需了解导出作业配额,请参阅“配额和限制”页面中的导出作业

INFORMATION_SCHEMA 中提供了导出作业的用量。 导出作业的 JOBS_BY_* 系统表中的作业条目包含 total_processed_bytes 值,该值可用于监控总用量以确保其保持在每天 50 TB 以下。如需了解如何查询 INFORMATION_SCHEMA.JOBS 视图以获取 total_processed_bytes 值,请参阅 INFORMATION_SCHEMA.JOBS 架构

查看当前配额用量

您可以运行 INFORMATION_SCHEMA 查询来查看在指定时间段内运行的作业的元数据,从而查看查询、加载、提取或复制作业的当前使用情况。您可以将当前用量与配额限制进行比较,以确定特定类型的作业的配额用量。以下示例查询使用 INFORMATION_SCHEMA.JOBS 视图按项目列出查询、加载、提取和复制作业的数量:

SELECT
  sum(case  when job_type="QUERY" then 1 else 0 end) as QRY_CNT,
  sum(case  when job_type="LOAD" then 1 else 0 end) as LOAD_CNT,
  sum(case  when job_type="EXTRACT" then 1 else 0 end) as EXT_CNT,
  sum(case  when job_type="COPY" then 1 else 0 end) as CPY_CNT
FROM `region-eu`.INFORMATION_SCHEMA.JOBS_BY_PROJECT
WHERE date(creation_time)= CURRENT_DATE()

您可以设置 Cloud Monitoring 提醒政策,以提供导出字节数的通知。

  1. 在 Google Cloud 控制台中,进入 Monitoring 页面。

    进入 Monitoring

  2. 在导航窗格中,选择 Metrics Explorer

  3. MQL 查询编辑器中,设置提醒以监控每天导出的字节数,如以下示例所示:

    fetch consumer_quota
      | filter resource.service == 'bigquery.googleapis.com'
      | { metric serviceruntime.googleapis.com/quota/rate/net_usage
          | align delta_gauge(1m)
          | group_by [resource.project_id, metric.quota_metric, resource.location],
              sum(value.net_usage)
        ; metric serviceruntime.googleapis.com/quota/limit
          | filter metric.limit_name == 'ExtractBytesPerDay'
          | group_by [resource.project_id, metric.quota_metric, resource.location],
              sliding(1m), max(val()) }
      | ratio
      | every 1m
      | condition gt(val(), 0.01 '1')
    
  4. 如需设置提醒,请点击运行查询

如需了解详情,请参阅使用 MQL 的提醒政策

问题排查

如需诊断提取作业存在的问题,您可以使用 Logs Explorer 来查看特定提取作业的日志并找出可能的错误。以下 Logs Explorer 过滤条件会返回提取作业的相关信息:

resource.type="bigquery_resource"
protoPayload.methodName="jobservice.insert"
(protoPayload.serviceData.jobInsertRequest.resource.jobConfiguration.query.query=~"EXPORT" OR
protoPayload.serviceData.jobCompletedEvent.eventName="extract_job_completed" OR
protoPayload.serviceData.jobCompletedEvent.job.jobConfiguration.query.query=~"EXPORT")

价格

如需了解数据导出价格,请参阅 BigQuery 价格页面。

导出数据后,如果您将数据存储在 Cloud Storage 中,则需要为此付费。如需了解详情,请参阅 Cloud Storage 价格

表安全性

如需控制对 BigQuery 中表的访问权限,请参阅表访问权限控制简介

后续步骤