【问题标题】:Retrieving BigQuery validation errors when loading JSONL data via the Python API通过 Python API 加载 JSONL 数据时检索 BigQuery 验证错误
【发布时间】:2022-02-03 02:44:30
【问题描述】:

在将 JSONL 文件加载到 BigQuery 时,如何检索与验证错误相关的更多信息? (问题不是解决问题)

示例代码:

from google.cloud.bigquery import (
    LoadJobConfig,
    QueryJobConfig,
    Client,
    SourceFormat,
    WriteDisposition
)

# variables depending on the environment
filename = '...'
gcp_project_id = '...'
dataset_name = '...'
table_name = '...'
schema = [ ... ]

# loading data
client = Client(project=project_id)
dataset_ref = client.dataset(dataset_name)
table_ref = dataset_ref.table(table_name)
job_config = LoadJobConfig()
job_config.source_format = SourceFormat.NEWLINE_DELIMITED_JSON
job_config.write_disposition = WriteDisposition.WRITE_APPEND
job_config.schema = schema
LOGGER.info('loading from %s', filename)
with open(filename, "rb") as source_file:
    job = client.load_table_from_file(
        source_file, destination=table_ref, job_config=job_config
    )

    # Waits for table cloud_data_store to complete
    job.result()

这里我使用 bigquery-schema-generator 生成架构(因为 BigQuery 否则只会查看前 100 行)。

运行可能会出现以下错误消息 (google.api_core.exceptions.BadRequest):

400 Error while reading data, error message: JSON表遇到太多错误,放弃。行数:1;错误: 1. 请查看 errors[] 集合了解更多详情。

查看errors属性基本上没有提供任何新信息:

[{'reason': 'invalid',
  'message': 'Error while reading data, error message: JSON table encountered too many errors, giving up. Rows: 1; errors: 1. Please look into the errors[] collection for more details.'}]

我还查看了 __dict__ 的异常,但没有透露任何进一步的信息。

尝试使用bq 命令行(在这种情况下没有显式架构)加载表会产生更有用的消息:

加载操作中的 BigQuery 错误:处理作业“...”时出错:提供的架构与表 不匹配。字段 已将类型从 TIMESTAMP 更改为 日期

我现在的问题是如何从 Python API 中检索到如此有用的消息?

基于已接受答案的解决方案

这是一个可以添加的副本和过去的解决方法,以便默认显示更多信息。 (可能有缺点)

import google.cloud.exceptions
import google.cloud.bigquery.job


def get_improved_bad_request_exception(
    job: google.cloud.bigquery.job.LoadJob
) -> google.cloud.exceptions.BadRequest:
    errors = job.errors
    result = google.cloud.exceptions.BadRequest(
        '; '.join([error['message'] for error in errors]),
        errors=errors
    )
    result._job = job
    return result


def wait_for_load_job(
    job: google.cloud.bigquery.job.LoadJob
):
    try:
        job.result()
    except google.cloud.exceptions.BadRequest as exc:
        raise get_improved_bad_request_exception(job) from exc

然后直接调用wait_for_load_job(job) 而不是job.result(),将导致更有用的异常(错误消息和errors 属性)。

【问题讨论】:

    标签: python google-bigquery


    【解决方案1】:

    为了能够显示更有用的错误消息,您可以导入 google.api_core.exceptions.BadRequest 以捕获异常,然后使用 LoadJob attribute errors 从作业中获取详细的错误消息。

    from google.api_core.exceptions import BadRequest
    ...
    ...
    try:
        load_job.result()# Waits for the job to complete.
    except BadRequest:
        for error in load_job.errors:
            print(error["message"])  # error is of type dictionary
    

    为了测试,我使用了示例代码BQ load json data 并更改了输入文件以产生错误。在文件中,我将"post_abbr" 的值从字符串更改为数组值。

    使用的文件:

    {"name": "Alabama", "post_abbr": "AL"}
    {"name": "Alaska", "post_abbr":  "AK"}
    {"name": "Arizona", "post_abbr": [65,2]}
    

    当应用上面的代码 sn-p 时,请参阅下面的输出。最后一条错误消息显示了关于 "post_abbr" 接收非重复字段的数组的实际错误。

    Error while reading data, error message: JSON table encountered too many errors, giving up. Rows: 3; errors: 1. Please look into the errors[] collection for more details.
    Error while reading data, error message: JSON processing encountered too many errors, giving up. Rows: 3; errors: 1; max bad: 0; error percent: 0
    Error while reading data, error message: JSON parsing error in row starting at position 78: Array specified for non-repeated field: post_abbr.
    

    【讨论】:

    • 谢谢。所以关键是看job的errors集合。我想知道为什么异常错误不包括作业的所有错误。
    猜你喜欢
    • 1970-01-01
    • 2018-11-07
    • 2010-12-26
    • 2018-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-25
    • 1970-01-01
    相关资源
    最近更新 更多