如何在 BigQuery 客户端 Python API 中以原子方式覆盖表

Posted

技术标签:

【中文标题】如何在 BigQuery 客户端 Python API 中以原子方式覆盖表【英文标题】:How to overwrite a table in atomic fashion in BigQuery client Python API 【发布时间】:2018-09-01 23:32:03 【问题描述】:

这是我从 GCP 文档中用作参考的代码 sn-p:

job_config = bigquery.QueryJobConfig()
# Set the destination table
table_ref = client.dataset(dataset_id).table('your_table_id')
job_config.destination = table_ref
sql = """
    SELECT corpus
    FROM `bigquery-public-data.samples.shakespeare`
    GROUP BY corpus;
"""

# Start the query, passing in the extra configuration.
query_job = client.query(
    sql,
    # Location must match that of the dataset(s) referenced in the query
    # and of the destination table.
    location='US',
    job_config=job_config)  # API request - starts the query

query_job.result()  # Waits for the query to finish
print('Query results loaded to table '.format(table_ref.path))

这工作正常,但如果表已经存在,这会吐出一个错误。我知道如何先删除表,但我想知道是否有办法让它以原子方式覆盖表,以便表始终存在。

【问题讨论】:

你可以用CREATE OR REPLACE TABLE,对吧? 你的评论给了我一个提示。如果我删除“job_config.destination”,然后添加“CREATE OR REPLACE TABLE ... AS”,它就成功了!谢谢! 【参考方案1】:

您可以通过设置 create_disposition 和 write_disposition 的组合来控制结果的持久化方式。 python 库在QueryJobConfig 中公开了这些选项,并链接到来自 REST API 文档的更多详细信息。

对于查询,写入处置的默认行为是WRITE_EMPTY,如果表已经存在,则会导致失败。将其切换为 WRITE_TRUNCATE 应该可以原子替换您正在寻找的数据。

TL;DR: 只需将其添加到您的工作配置中:

job_config.write_disposition = bigquery.WriteDisposition.WRITE_TRUNCATE

【讨论】:

以上是关于如何在 BigQuery 客户端 Python API 中以原子方式覆盖表的主要内容,如果未能解决你的问题,请参考以下文章

在 google bigquery 中,如何使用 google python 客户端使用 javascript UDF

如何使用 Python gcloud.bigquery 客户端跳过标题行?

BigQuery Python 客户端 - 超时参数的含义,以及如何设置查询结果超时

如何使用 python 在 BigQuery 中执行 job.insert?我得到“需要登录”,但可以列出所有表和数据集

如何将查询结果插入 BigQuery 前缀表

如何在 BigQuery SQL 中安全地参数化表/列名称?