导出表数据

本页面介绍了如何从 BigQuery 表格导出或提取数据。

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

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

所需权限

要将数据导出到 Cloud Storage,您需要具有访问包含这些数据的 BigQuery 表的权限、运行导出作业的权限以及将数据写入 Cloud Storage 存储分区的权限。

BigQuery 权限

  • 要导出数据,您至少必须获得 bigquery.tables.export 权限。以下预定义的 Cloud IAM 角色具有 bigquery.tables.export 权限:

    • bigquery.dataViewer
    • bigquery.dataOwner
    • bigquery.dataEditor
    • bigquery.admin
  • 为运行导出作业,您至少必须具有 bigquery.jobs.create 权限。以下预定义的 Cloud IAM 角色具有 bigquery.jobs.create 权限:

    • bigquery.user
    • bigquery.jobUser
    • bigquery.admin

Cloud Storage 权限

  • 要将数据写入现有 Cloud Storage 存储分区,您必须具有 storage.objects.create 权限。以下预定义的 Cloud IAM 角色具有 storage.objects.create 权限:

    • storage.objectCreator
    • storage.objectAdmin
    • storage.admin

导出限制

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

  • 您不能将表数据导出到本地文件、Google 表格或 Google 云端硬盘。系统唯一支持的导出位置是 Cloud Storage。如需了解如何保存查询结果,请参阅下载和保存查询结果
  • 您最多可以将 1 GB 的表数据导出到单个文件中。如果要导出 1 GB 以上的数据,请使用通配符将数据导出到多个文件。将数据导出到多个文件时,各个文件的大小会有所不同。
  • 您不能使用 CSV 格式导出嵌套数据和重复数据。Avro 和 JSON 导出格式支持嵌套数据和重复数据。
  • 使用 JSON 格式导出数据时,INT64(整数)数据类型会编码为 JSON 字符串,以便在其他系统读取数据时保留 64 位精度。
  • 您不能在一个导出作业中导出多个表中的数据。
  • 从分区的表导出数据时,您不能导出单个分区。
  • 使用 GCP Console 或经典版 BigQuery 网页界面导出数据时,您不能选择 GZIP 以外的压缩类型。

位置注意事项

在选择数据的位置时,请考虑以下事项:

  • 共置 Cloud Storage 存储分区,以导出数据。
    • 导出数据时,区域或多区域 Cloud Storage 存储分区必须与 BigQuery 数据集位于相同位置。例如,如果您的 BigQuery 数据集位于 EU 多区域位置,则包含您要导出的数据的 Cloud Storage 存储分区必须位于 EU 的区域或多区域位置。
    • 如果您的数据集位于区域位置,则您的 Cloud Storage 存储分区必须是同一位置的区域存储分区。例如,如果您的数据集位于东京区域,则您的 Cloud Storage 存储分区必须是位于东京的区域存储分区。
    • 例外情况:如果您的数据集位于 US 多区域位置,则可以将数据导出到任何区域或多区域位置的 Cloud Storage 存储分区中。
  • 制定数据管理计划。
    • 如果您选择区域存储资源(如 BigQuery 数据集或 Cloud Storage 存储分区),请制定按地理位置管理数据的计划。

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

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

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

复制数据集

要查看复制数据集的步骤(包括跨区域),请参阅复制数据集

移动数据集

要手动将数据集从一个位置移动到另一个位置,请按照以下流程操作:

  1. 从 BigQuery 表中将数据导出到数据集所在位置的单区域或多区域 Cloud Storage 存储分区中。例如,如果您的数据集位于 EU 多区域位置,请将您的数据导出到位于 EU 的区域或多区域存储分区中。

    从 BigQuery 导出数据不会产生费用,但是将导出的数据存储在 Cloud Storage 中会产生费用。BigQuery 导出需要遵循与导出作业相关的限制。

  2. 将数据从 Cloud Storage 存储分区复制或移动到新位置的区域或多区域存储分区中。例如,如果要将数据从 US 多区域位置移动到东京区域位置,则会将数据转移到位于东京的区域存储分区。如需了解如何转移 Cloud Storage 对象,请参阅 Cloud Storage 文档中的重命名、复制和移动对象

    请注意,在不同区域之间转移数据会在 Cloud Storage 中产生网络出站费用

  3. 将数据转移到新位置的 Cloud Storage 存储分区后,(在新位置)创建一个新的 BigQuery 数据集。然后,将数据从 Cloud Storage 存储分区加载到 BigQuery 中。

    您不需要为将数据加载到 BigQuery 而付费,但在删除数据或存储分区之前,您需要为在 Cloud Storage 中存储数据支付费用。加载完毕后,您还需要为在 BigQuery 中存储数据支付费用。将数据加载到 BigQuery 需要遵循与加载作业相关的限制。

如需详细了解如何使用 Cloud Storage 存储和移动大型数据集,请参阅使用 Cloud Storage 处理大数据

导出格式和压缩类型

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

数据格式 支持的压缩类型 详情
CSV GZIP

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

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

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

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

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

导出存储在 BigQuery 中的数据

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

  • 使用 GCP Console 或经典版 BigQuery 网页界面
  • 使用 bq extract CLI 命令
  • 通过 API 或客户端库提交 extract 作业

导出表数据

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

Console

  1. 在 GCP Console 中打开 BigQuery 网页界面。
    转到 GCP Console

  2. 在导航面板的资源部分,展开您的项目并点击您的数据集以将其展开。找到并点击包含要导出的数据的表。

  3. 在窗口右侧,点击导出,然后选择导出到 Cloud Storage (Export to Cloud Storage)

    导出数据

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

    • 选择 Cloud Storage 位置部分,浏览并找到您要导出数据的目标存储分区、文件夹或文件。
    • 导出格式中,选择导出数据的格式:CSV、JSON(以换行符分隔)或 Avro。
    • 压缩部分,接受默认值 None 或选择 GZIP。Avro 格式不能与 GZIP 压缩搭配使用。要压缩 Avro 数据,请使用 bq 命令行工具或 API,并指定 Avro 数据支持的一种压缩类型(DEFLATESNAPPY)。
    • 点击导出以导出表。

要检查作业进度,请在导航窗格顶部附近查找导出作业的作业记录

经典版界面

  1. 转到 BigQuery 网页界面。
    转到 BigQuery 网页界面

  2. 在导航窗格中,点击您的数据集以将其展开。

  3. 找到包含要导出的数据的表,点击其旁边的向下箭头图标 向下箭头图标图片

  4. 选择 Export table 以显示 Export to Cloud Storage 对话框。

  5. Export to Cloud Storage 对话框中,执行以下操作:

    • Export format 中,选择导出数据的格式:CSV、JSON(以换行符分隔)或 Avro。
    • Compression 部分,接受默认值 None 或选择 GZIP。Avro 格式不能与 GZIP 压缩搭配使用。要压缩 Avro 数据,请使用 bq 命令行工具或 API,并指定 Avro 数据支持的一种压缩类型(DEFLATESNAPPY)。
    • Cloud Storage URI 文本框中,输入格式为 gs://bucket_name/filename.ext 的有效 URI,其中 bucket_name 是您的 Cloud Storage 存储分区名称,filename.ext 是目标文件的名称和扩展名。BigQuery 数据集和 Cloud Storage 存储分区必须位于同一位置
    • 点击 OK 以导出表。

在作业运行过程中,导航窗格中表的名称旁边会显示 (extracting)。要检查作业进度,请在靠近导航窗格顶部的位置查看 Extract 作业的 Job History

CLI

使用带有 --destination_format 标志的 bq extract 命令。

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

其他可选标志包括:

  • --compression:此标志表示用于导出的文件的压缩类型。
  • --field_delimiter:此标志表示指明 CSV 导出的输出文件中各列之间边界的字符。可以使用 \ttab 作为制表符分隔符。
  • --print_header:如果指定了此标志,并且格式设置中带有标题(如 CSV),则系统会打印标题行。
bq --location=location extract \
--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_JSONAVRO
  • compression_type 是数据格式支持的压缩类型。CSVNEWLINE_DELIMITED_JSON 支持 GZIPAVRO 支持 DEFLATESNAPPY
  • delimiter 是指明 CSV 导出文件中各列之间边界的字符。您可以使用 \ttab 作为制表符。
  • boolean 为 truefalse设置为 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

API

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

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

  1. 创建一个提取作业,将其指向 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. 要检查作业状态,请调用 jobs.get(job_id),并使用初始请求返回的作业的 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 参考文档


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.PollUntilCompleted();  // Waits for the job to complete.
        Console.Write($"Exported table to {destinationUri}.");
    }
}

Go

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

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

// For example, gcsUri = "gs://mybucket/shakespeare.csv"
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
}

Java

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

Job job = table.extract(format, gcsUrl);
// Wait for the job to complete
try {
  Job completedJob =
      job.waitFor(
          RetryOption.initialRetryDelay(Duration.ofSeconds(1)),
          RetryOption.totalTimeout(Duration.ofMinutes(3)));
  if (completedJob != null && completedJob.getStatus().getError() == null) {
    // Job completed successfully
  } else {
    // Handle error case
  }
} catch (InterruptedException e) {
  // Handle interrupted wait
}

Node.js

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

// 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);
  // load() waits for the job to finish
  console.log(`Job ${job.id} completed.`);

  // 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 参考文档

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';
// $bucketName = 'The Cloud Storage bucket Name';

$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 参考文档

# 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 = client.dataset(dataset_id, project=project)
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 参考文档

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 数据类型表示为 Avro LONG 类型。

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

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

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

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

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

“destinationUris”选项
单个 URI

如果要导出的表数据未超过 1 GB,请使用单个 URI。最常见的使用情形就是采用这种方式,因为导出的数据通常都小于 1 GB 上限值。

属性定义:

['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
...
多个通配符 URI

如果要对导出输出进行分区,请使用多个通配符 URI。如果您使用 Cloud Dataproc 等服务运行一项并行处理作业,则可以使用此选项。请确定有多少工作器可用于处理作业,并为每个工作器创建一个 URI。BigQuery 将每个 URI 位置视为一个分区,并使用并行处理将您的数据分片到每个位置的多个文件。假设每个 URI 中只有一个通配符运算符,每个 URI 都是唯一的,并且 URI 的数量不超过配额政策,那么您可以在文件名中使用所需的任何模式。

当您传递多个通配符 URI 时,BigQuery 会在每个分区的末尾创建一个特殊文件,用于指示组中的最终文件。此文件名会指明 BigQuery 创建的分片数。

例如,如果通配符 URI 为 gs://my-bucket/file- name-<worker number>-*.json,并且 BigQuery 创建了 80 个分片文件,则零记录文件名为 gs://my-bucket/file-name-<worker number>-000000000080.json。通过此文件名,您可以确定 BigQuery 创建了 80 个分片文件(文件名从 000000000000 到 000000000079)。

请注意,零记录文件包含的字节数可能多于 0 个,具体取决于数据格式,例如以带有列标题的 CSV 格式导出数据时就是如此。

字符串模式:

gs://my-bucket/file-name-<worker number>-*.json

属性定义:


['gs://my-bucket/file-name-1-*.json',
'gs://my-bucket/file-name-2-*.json',
'gs://my-bucket/file-name-3-*.json']

创建:

此示例假设 BigQuery 在每个分区中创建 80 个分片文件。


gs://my-bucket/file-name-1-000000000000.json
gs://my-bucket/file-name-1-000000000001.json
...
gs://my-bucket/file-name-1-000000000080.json
gs://my-bucket/file-name-2-000000000000.json
gs://my-bucket/file-name-2-000000000001.json
...
gs://my-bucket/file-name-2-000000000080.json
gs://my-bucket/file-name-3-000000000000.json
gs://my-bucket/file-name-3-000000000001.json
...
gs://my-bucket/file-name-3-000000000080.json

配额政策

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

价格

目前,从 BigQuery 导出数据是免费的,但有相关的 BigQuery 配额和限制。如需详细了解 BigQuery 价格,请参阅价格页面。

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

后续步骤

此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

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