从 Cloud Storage 加载 Avro 数据

从 Cloud Storage 加载 Avro 文件

Avro 是一种开放源代码数据格式,它将序列化数据与数据的架构捆绑在同一文件中。

从 Cloud Storage 加载 Avro 数据时,可以将数据加载到新的表或分区中,也可以附加到或覆盖现有的表或分区。当数据加载到 BigQuery 时,它会转化为适用于 Capacitor 的列式格式(BigQuery 的存储格式)。

将数据从 Cloud Storage 加载到 BigQuery 表时,包含该表的数据集必须与 Cloud Storage 存储分区位于同一区域或多区域位置。

如需详细了解如何从本地文件加载 Avro 数据,请参阅从本地数据源将数据加载到 BigQuery

Avro 的优势

Avro 是将数据加载到 BigQuery 的首选格式。与加载 CSV 和 JSON(换行符分隔)相比,加载 Avro 文件具有以下优势:

  • Avro 二进制格式:
    • 加载速度更快。即使数据块被压缩,也可以并行读取数据。
    • 无需输入或序列化。
    • 更容易解析,因为没有其他格式(如 ASCII)所存在的编码问题。
  • 在您将 Avro 文件加载到 BigQuery 时,系统会自动从自描述源数据中检索表架构。

所需权限

在将数据加载到 BigQuery 时,您需要拥有项目级或数据集级的权限,才能将数据加载到新的或现有的 BigQuery 表和分区中。如果要从 Cloud Storage 加载数据,您还需要访问包含该数据的存储分区。

BigQuery 权限

如果您要将数据从 Cloud Storage 加载到 BigQuery 中,必须被授予项目级或数据集级的 bigquery.dataOwnerbigquery.dataEditor 角色。这两个角色允许用户和组将数据加载到新表中,或将数据附加到现有表或覆盖现有表。

若授予项目级角色,则用户或组有权将数据加载到项目中任一数据集的表中。若授予数据集级角色,则用户或组只能将数据加载到该数据集的表中。

如需详细了解如何配置数据集访问权限,请参阅控制对数据集的访问权限。要详细了解 BigQuery 中的 IAM 角色,请参阅访问权限控制

Cloud Storage 权限

要从 Cloud Storage 存储分区加载数据,您必须被授予项目级或相应单个存储分区的 storage.objects.get 权限。如果要使用 URI 通配符,您还必须拥有 storage.objects.list 权限。

可以通过授予预定义的 IAM 角色 storage.objectViewer 来提供 storage.objects.getstorage.objects.list 权限。

Avro 架构

在您将 Avro 文件加载到 BigQuery 时,系统会自动使用源数据检索表架构。当 BigQuery 从源数据中检索架构时,将使用按字母顺序排列的最后一个文件。

例如,您在 Cloud Storage 中具有以下 Avro 文件:

gs://mybucket/00/
  a.avro
  z.avro
gs://mybucket/01/
  b.avro

此命令可通过单个 CLI 命令加载所有文件(以英文逗号分隔列表形式),而架构来源于 mybucket/01/b.avro

bq --location=US load --source_format=AVRO [DATASET].[TABLE_NAME] "gs://mybucket/00/*.avro","gs://mybucket/01/*.avro"

在导入多个具有不同 Avro 架构的 Avro 文件时,所有架构都必须与 Avro 的架构解决方案兼容。

当 BigQuery 检测到架构时,某些 Avro 数据类型会转换为 BigQuery 数据类型,从而与 BigQuery SQL 语法兼容。如需了解详细信息,请参阅 Avro 转化

Avro 压缩

不支持压缩的 Avro 文件,但支持压缩的数据块。BigQuery 支持 DEFLATE 和 Snappy 编解码器。

向新表加载 Avro 数据

要将 Cloud Storage 中的 Avro 数据加载到新 BigQuery 表中,或将 Avro 数据附加到现有表中,请执行以下操作:

Console

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

  2. 在导航面板的资源部分中,展开您的项目并选择数据集。

  3. 在窗口右侧的详细信息面板中,点击创建表。加载数据的过程与创建空表的过程相同。

    创建表

  4. 创建表页面的来源部分,执行以下操作:

    • 基于以下数据创建表部分,选择所需的来源类型。

      创建表来源

    • 在来源字段中,浏览并找到相应的文件/Cloud Storage 存储分区,或输入 Cloud Storage URI。请注意,BigQuery 网页界面不支持添加多个 URI,但支持使用通配符。Cloud Storage 存储分区必须与您要创建的表所属的数据集位于同一位置。

      选择文件

    • 对于文件格式,请选择 Avro

  5. 创建表页面的目标位置部分,执行以下操作:

    • 数据集名称部分,选择适当的数据集。

      选择数据集

    • 表名称字段中,输入您要在 BigQuery 中创建的表的名称。

    • 验证表类型是否设置为原生表

  6. Schema 部分中,不必执行任何操作。系统会从 Avro 文件推断架构。

  7. 点击创建表

传统版界面

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

  2. 在导航面板中,将鼠标悬停在数据集上,点击向下箭头图标 向下箭头图标图片,然后点击 Create new table。加载数据的过程与创建空表的过程相同。

  3. Create Table 页面的 Source Data 部分,执行以下操作:

    • Location 部分选择 Cloud Storage,然后在来源字段中输入 Cloud Storage URI。请注意,BigQuery 网页界面不支持添加多个 URI,但支持使用通配符。Cloud Storage 存储分区必须与您要创建的表所属的数据集位于同一位置。
    • 对于 File format,请选择 Avro
  4. Create Table 页面的 Destination Table 部分,执行以下操作:

    • Table name 部分,选择适当的数据集,然后在表名称字段中输入要在 BigQuery 中创建的表的名称。
    • 验证 Table type 是否设为 Native table
  5. Schema 部分中,不必执行任何操作。系统会从 Avro 文件推断架构。

  6. 点击 Create Table

命令行

使用 bq load 命令,指定 AVRO 作为 source_format,并添加 Cloud Storage URI。您可以添加单个 URI、以英文逗号分隔的 URI 列表或含有通配符的 URI。

提供 --location 标志并将值设置为您的位置

bq --location=[LOCATION] load --source_format=[FORMAT] [DATASET].[TABLE] [PATH_TO_SOURCE]

其中:

  • [LOCATION] 是您的位置。如果数据位于 USEU 多区域位置,则 --location 标志为可选项。例如,如果您在东京区域使用 BigQuery,则将该标志的值设置为 asia-northeast1。您可以使用 .bigqueryrc 文件设置位置的默认值。
  • [FORMAT] 为 AVRO。
  • [DATASET] 是一个现有数据集。
  • [TABLE] 是要向其中加载数据的表的名称。
  • [PATH_TO_SOURCE] 是完全限定的 Cloud Storage URI 或以英文逗号分隔的 URI 列表。您还可以使用通配符

示例:

  • 以下命令将 gs://mybucket/mydata.avro 中的数据加载到 mydataset 中名为 mytable 的表中。mybucketmydataset 创建于 US 多区域位置。

    bq --location=US load --source_format=AVRO mydataset.mytable gs://mybucket/mydata.avro
    
  • 以下命令将 gs://mybucket/ 中多个文件的数据加载到 mydataset 中名为 mytable 的表中。Cloud Storage URI 使用通配符。 mybucketmydataset 创建于 US 多区域位置。

    bq --location=US load --source_format=AVRO mydataset.mytable gs://mybucket/mydata*.avro
    
  • 以下命令将 gs://mybucket/ 中多个文件的数据加载到 mydataset 中名为 mytable 的表中。该命令包含 Cloud Storage URI(带有通配符)的英文逗号分隔列表。mybucketmydataset 创建于 asia-northeast1 区域。

    bq --location=asia-northeast1 load --autodetect --source_format=AVRO mydataset.mytable "gs://mybucket/00/*.avro","gs://mybucket/01/*.avro"
    

API

设置以下属性,以便使用 API 加载 Avro 数据。

  1. 创建指向 Cloud Storage 中源数据的加载作业

  2. 作业资源jobReference 部分的 location 属性中,指定您的位置

  3. sourceUris 必须采用完全限定形式,格式为 gs://[BUCKET]/[OBJECT]。每个 URI 都可以包含一个“*”通配符

  4. sourceFormat 属性设置为 AVRO,以指定 Avro 数据格式。

  5. 要检查作业状态,请调用 jobs.get([JOB_ID]*),其中 [JOB_ID] 是初始请求返回的作业的 ID。

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

API 说明:

  • 加载作业不可分割。也就是说,如果加载作业失败,则所有数据都不可用;如果加载作业成功,则所有数据全部可用。

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

  • 对指定的作业 ID 调用 jobs.insert() 在效果上是幂等的;换句话说,您可以对同一作业 ID 重试多次,但最多只有一次操作会成功。

Python

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

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

dataset_ref = client.dataset(dataset_id)
job_config = bigquery.LoadJobConfig()
job_config.source_format = bigquery.SourceFormat.AVRO
uri = "gs://cloud-samples-data/bigquery/us-states/us-states.avro"

load_job = client.load_table_from_uri(
    uri, dataset_ref.table("us_states"), job_config=job_config
)  # API request
print("Starting job {}".format(load_job.job_id))

load_job.result()  # Waits for table load to complete.
print("Job finished.")

destination_table = client.get_table(dataset_ref.table("us_states"))
print("Loaded {} rows.".format(destination_table.num_rows))

使用 Avro 数据覆盖表

您可以从源文件将其他数据加载到表中,也可以通过附加查询结果执行此操作。

在控制台或经典版 BigQuery 网页界面中,使用 Write preference 选项指定从源文件或查询结果加载数据时要执行的操作。

将其他数据加载到表中时,可选择以下选项:

控制台选项 传统版界面选项 CLI 标志 BigQuery API 属性 说明
只写入空白表 Write if empty WRITE_EMPTY 仅当表为空时才写入数据。
附加到表 Append to table --noreplace--replace=false;如果未指定 --[no]replace,则默认为附加 WRITE_APPEND (默认)在表末尾附加数据。
覆盖表 Overwrite table --replace--replace=true WRITE_TRUNCATE 在写入新数据之前清空表中的所有现有数据。

默认情况下,加载作业会将数据附加到表中。要使用加载作业覆盖表数据,请执行以下操作:

Console

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

  2. 在导航面板的资源部分中,展开您的项目并选择数据集。

  3. 在窗口右侧的详细信息面板中,点击创建表。加载数据的过程与创建空表的过程相同。

  4. 创建表页面的来源部分,执行以下操作:

    • 基于以下数据创建表中选择所需的来源类型,然后在来源字段中,浏览并找到文件/Cloud Storage 存储分区,或输入 Cloud Storage URI。请注意,BigQuery 网页界面不支持添加多个 URI,但支持使用通配符。Cloud Storage 存储分区必须与您要创建的表所属的数据集位于同一位置。
    • 对于文件格式,请选择 Avro
  5. 创建表页面的目标位置部分,执行以下操作:

    • 对于数据集名称,请选择相应的数据集,然后在表名称字段中输入您要在 BigQuery 中创建的表的名称。
    • 验证表类型是否设置为原生表
  6. Schema 部分中,不必执行任何操作。系统会从 Avro 文件推断架构。

  7. 高级选项 (Advance options) 部分,为写入偏好设置选择只写入空白表附加到表覆盖表

  8. 点击创建表

经典版界面

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

  2. 在导航面板中,将鼠标悬停在数据集上,点击向下箭头图标 向下箭头图标图片,然后点击 Create new table。加载数据的过程与创建空表的过程相同。

  3. Create Table 页面的 Source Data 部分,执行以下操作:

    • Location 部分选择 Cloud Storage,然后在来源字段中输入 Cloud Storage URI。请注意,此界面不支持添加多个 URI,但支持使用通配符。Cloud Storage 存储分区必须与您要向其中附加数据或覆盖其数据的表所属的数据集位于同一位置。
    • 对于 File format,请选择 Avro
  4. Create Table 页面的 Destination Table 部分,执行以下操作:

    • Table name 部分,选择适当的数据集,然后在表名称字段中输入您要向其中附加数据或覆盖其数据的表的名称。
    • 验证 Table type 是否设为 Native table
  5. Schema 部分中,无需执行任何操作。系统会从 Avro 文件推断架构信息。

  6. 对于 Write preference,请在 Options 部分选择 Write if emptyAppend to tableOverwrite table

    使用添加字段添加架构

  7. 点击 Create Table

命令行

输入带 bq load 标志的 --replace 命令以覆盖表。提供 --location 标志并将值设置为您的位置。使用 --noreplace 标志将数据附加到表中。如果未指定标记,则默认为附加数据。

bq --location=[LOCATION] load --[no]replace [DATASET].[TABLE] [PATH_TO_SOURCE]

其中:

  • [LOCATION] 是您的位置。如果您的数据位于 USEU 多区域位置,则 --location 标志为可选。您可以使用 .bigqueryrc 文件设置该位置的默认值。
  • [DATASET] 是一个现有数据集。
  • [TABLE] 是要向其中加载数据的表的名称。
  • [PATH_TO_SOURCE] 是完全限定的 Cloud Storage URI 或以英文逗号分隔的 URI 列表。您还可以使用通配符

示例:

  • 以下命令加载 gs://mybucket/mydata.avro 中的数据,并覆盖 mydataset 中名为 mytable 的表。mybucketmydataset 创建于 US 多区域位置。

    bq --location=US load --replace --source_format=AVRO mydataset.mytable gs://mybucket/mydata.avro
    
  • 以下命令加载 gs://mybucket/mydata.avro 中的数据,并将数据附加到 mydataset 中名为 mytable 的表中。mybucketmydataset 创建于 asia-northeast1 区域。

    bq --location=asia-northeast1 load --noreplace --source_format=AVRO mydataset.mytable gs://mybucket/mydata.avro
    

API

设置以下属性,以便使用 API 加载 CSV 数据。

  1. 创建指向 Cloud Storage 中源数据的加载作业

  2. 作业资源jobReference 部分的 location 属性中,指定您的位置

  3. sourceUris 必须采用完全限定形式,格式为 gs://[BUCKET]/[OBJECT]。要添加多个 URI,可采用英文逗号分隔列表的形式。请注意,从 Cloud Storage 加载 CSV 数据时,也可使用通配符

  4. sourceFormat 属性设置为 AVRO,以指定数据格式。

  5. writeDisposition 属性设置为 WRITE_TRUNCATEWRITE_APPENDWRITE_EMPTY,以指定写入首选项。

Python

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

# from google.cloud import bigquery
# client = bigquery.Client()
# table_ref = client.dataset('my_dataset').table('existing_table')

job_config = bigquery.LoadJobConfig()
job_config.write_disposition = bigquery.WriteDisposition.WRITE_TRUNCATE
job_config.source_format = bigquery.SourceFormat.AVRO
uri = "gs://cloud-samples-data/bigquery/us-states/us-states.avro"
load_job = client.load_table_from_uri(
    uri, table_ref, job_config=job_config
)  # API request
print("Starting job {}".format(load_job.job_id))

load_job.result()  # Waits for table load to complete.
print("Job finished.")

destination_table = client.get_table(table_ref)
print("Loaded {} rows.".format(destination_table.num_rows))

Avro 转换

BigQuery 将 Avro 数据类型转化为以下 BigQuery 数据类型:

基本类型

Avro 数据类型 BigQuery 数据类型 备注
null BigQuery 会忽略这些值
boolean BOOLEAN
int INTEGER
long INTEGER
float FLOAT
double FLOAT
bytes BYTES
bytes(具有 decimal 逻辑类型 NUMERIC
string STRING 仅限 UTF-8

复合类型

Avro 数据类型 BigQuery 数据类型 备注
record RECORD
  • 忽略别名
  • 文档转换为字段描述
  • 默认值在读取时设置
  • 忽略顺序
  • 删除递归字段(仅保留递归字段的第一级嵌套)
enum STRING
  • 字符串是枚举的符号值
  • 忽略别名
  • 文档转换为字段描述
array 重复字段 不支持数组的数组。忽略仅包含 NULL 类型的数组。
map<T> RECORD BigQuery 将 Avro 映射<T> 字段转换为包含两个字段(键和值)的重复 RECORD。BigQuery 将键存储为 STRING,并将值转换为 BigQuery 中相应的数据类型。
union
  • 可以为 Null 的字段
  • 包含可以为 Null 的字段列表的 RECORD
  • 当 union 只有一个非 null 类型时,它会转换为可以为 Null 的字段。
  • 否则,它将转换为包含可以为 Null 的字段列表的 RECORD。读取时,系统只会设置其中一个字段。
fixed BYTES
  • 忽略别名
  • 忽略大小

逻辑类型

默认情况下,BigQuery 会忽略 logicalType 属性,并改为使用基础 Avro 类型。

Avro 逻辑类型 BigQuery 数据类型
date INTEGER
time-millis INTEGER
time-micros INTEGER(转化自 LONG)
timestamp-millis INTEGER(转化自 LONG)
timestamp-micros INTEGER(转化自 LONG)
duration BYTES(转化自大小为 12 的 fixed 类型)
decimal NUMERIC(请参阅 Decimal 逻辑类型

要将 Avro 逻辑类型转换为其对应的 BigQuery 数据类型,请使用命令行工具将 --use_avro_logical_types 标志设置为 True;或者在调用 jobs.insert 方法创建加载作业时,在作业资源中设置 useAvroLogicalTypes 属性。

下表显示 Avro 逻辑类型到 BigQuery 数据类型的转换。

Avro 逻辑类型 转换的 BigQuery 数据类型
date DATE
time-millis TIME
time-micros TIME
timestamp-millis TIMESTAMP
timestamp-micros TIMESTAMP
duration BYTES(由大小为 12 的 fixed 类型转换而来)
decimal NUMERIC(请参阅 Decimal 逻辑类型

要详细了解 Avro 数据类型,请参阅 Apache Avro™ 1.8.2 规范

decimal 逻辑类型

具有 decimal 逻辑类型的 Avro bytes 类型的 precision 最多为 38(总位数),scale 最多为 9 (小数点右侧的数字)。整数位数(即 precision 减去 scale)最多可以是 29。例如,支持 precision 为 38、scale 为 9 的 decimal,因为整数位数为 29。不支持 precision 为 38、scale 为 5 的 decimal,因为整数位数为 33。

在将 bytes 列中具有 decimal 逻辑类型的 Avro 文件加载到现有表中时,表的架构定义中列的数据类型可以是 BYTESNUMERIC。如果列的数据类型为 BYTES,则忽略 Avro 文件中列上的 decimal 逻辑类型。

如需详细了解 Avro decimal 逻辑类型,请参阅 Apache Avro™ 1.8.2 规范

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

发送以下问题的反馈:

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