首页 > 解决方案 > BigQuery Python API:在 extract_table 作业期间保留空字段

问题描述

我有以下代码:

job_config = bigquery.ExtractJobConfig()
job_config.compression = bigquery.Compression.GZIP
job_config.destination_format = (
    bigquery.DestinationFormat.NEWLINE_DELIMITED_JSON)

destination_uri = 'gs://{}/{}'.format(bucket_name, gcs_filename)

extract_job = client.extract_table(
    table,
    destination_uri,
    job_config=job_config,
    location='US')  # API request
extract_job.result()  # Waits for job to complete.

(请注意,我正在其他地方获取我的表格对象。)

这可行,并将请求的表作为换行符分隔的 JSON 转储到 GCS。但是,表中的某些列可以为空,其中一些列确实包含空值。为了我们所有数据的一致性,我想在 json 结果中保留空值。有什么方法可以做到这一点而不必使用 avro?

这篇文章在这里:JSON 中的 Big Query 表提取,保留空值?... 建议实际查询表。我不认为这对我来说是一个选择,因为我正在提取的表每个包含数百万行。我正在查看的一个包含近 1 亿行,数据量超过 25GB。但是我还没有找到一种方法来设置提取作业以保留空值。

标签: pythongoogle-bigquery

解决方案


我认为最好的方法是首先使用查询作业。

  1. 你让你的表从某个地方提取并运行查询作业
  2. 以不带标题的 CSV 格式运行提取

有这样做的代码

job_config = bigquery.QueryJobConfig()
gcs_filename = 'file_with_nulls*.json.gzip'

table_ref = client.dataset(dataset_id).table('my_null_table')
job_config.destination = table_ref

job_config.write_disposition = bigquery.WriteDisposition.WRITE_TRUNCATE

# Start the query, passing in the extra configuration.
query_job = client.query(
    """#standardSql
    select TO_JSON_STRING(t) AS json from `project.dataset.table` as t ;""",
    location='US',
    job_config=job_config)

while not query_job.done():
    time.sleep(1)

#check if table successfully written
print("query completed")
job_config = bigquery.ExtractJobConfig()
job_config.compression = bigquery.Compression.GZIP
job_config.destination_format = (
    bigquery.DestinationFormat.CSV)
job_config.print_header = False

destination_uri = 'gs://{}/{}'.format(bucket_name, gcs_filename)

extract_job = client.extract_table(
    table_ref,
    destination_uri,
    job_config=job_config,
    location='US')  # API request
extract_job.result()
print("extract completed")

完成后 - 您可以删除您在步骤 1 中创建的临时表。如果您快速执行此操作,成本将非常低(每月 1TB 存储为 20 美元 - 因此即使 1 小时的 25GB 存储也将是 20/30/24 = 3 美分)


推荐阅读