【发布时间】: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 属性)。
【问题讨论】: