使用自动检测将动态架构 JSON 文件加载到 BigQuery table
Loading dynamic schema JSON files into a BigQuery table using autodetect
这个问题与 非常相似 - 但使用 python API,几年后 - 由于解决方案不完整,我认为它是最好开一个新问题。
我有一堆 ndjson 文件,每天在 GCS 上生成,我想将其加载到 BQ table。
来自 file_1.json
的几行示例:
{"a": 1, "b": 2, "c": [1,2,4], "d": "string"}
{"a": 1, "c": [2, 4], "d": "some_string"}
{"a": 1, "e": 4}
一个file_2.json
的例子:
{"a": 4, "e": 6, "f": {"g": 7, "h": "str"}}
{"a": 1, "c": [2, 4], "f": {"g": 5}}
大多数字段是可选的,每个文件中的每个文件记录理论上可以包含任意字段组合(目前从大约 50 个中选择,但将来会改变和增加)。同名字段的内容应该(抛开任何错误)包含相同的数据类型。
我想将一组文件(某一天的所有文件)加载到 BQ table,其架构将由文件中所有字段的并集组成,具有 NULL 值其中一行没有对应字段的键。
我希望在没有需要维护的模式的情况下这样做。
我目前的尝试:
job_config = bigquery.LoadJobConfig(
write_disposition="WRITE_TRUNCATE",
create_disposition="CREATE_IF_NEEDED",
autodetect=True,
ignore_unknown_values=True,
schema_update_option="ALLOW_FIELD_ADDITION",
source_format="NEWLINE_DELIMITED_JSON"
)
uri = "gs://my-bucket/test/*.json"
load_job = client.load_table_from_uri(
uri,
table_id,
location="EU",
job_config=job_config,
)
load_job.result()
使用 autodetect=True
来避免明确指定架构,但由于自动检测从单个文件扫描多达 500 行 - 某些字段可能一开始不会创建。
我希望 schema_update_option="ALLOW_FIELD_ADDITION"
(ref here) 能满足我的需要,但它不起作用。
我尝试过的另一种选择:
# Instead of wildcard, get blob list and convert to uris
blobs = storage_client.get_bucket(BUCKET).list_blobs(prefix=FOLDER)
uris = [f"gs://{BUCKET}/{blob.name}" for blob in blobs if blob.name.endswith(".json")]
job_config = bigquery.LoadJobConfig(
write_disposition="WRITE_APPEND", #Will append file by file
create_disposition="CREATE_IF_NEEDED",
autodetect=True,
schema_update_option="ALLOW_FIELD_ADDITION",
source_format="NEWLINE_DELIMITED_JSON"
)
for uri in uris:
load_job = client.load_table_from_uri(
uri,
table_id,
location="EU",
job_config=job_config,
)
load_job.result()
这效率较低,我想 - 但无论如何它也不起作用 - 收到此错误:
BadRequest: 400 Provided Schema does not match Table my-bucket:test.test_diff_schema. Cannot add fields (field: f)
同样,我想 schema_update_option="ALLOW_FIELD_ADDITION"
会避免 - 但它似乎只适用于预定义的模式,而不适用于自动检测。
欢迎任何想法,提前致谢!
在自动检测中,BigQuery 读取了一堆第一行并尝试检测模式。在这第一个 运行 之后,模式已设置并且在整个摄取过程中无法更改。您可以使用“ignore_unknown_values”选项跳过与自动检测架构不匹配的值。
但它不会如你所愿。我知道 BigQuery 团队致力于更好的 JSON 集成。目前,我只能建议您将 JSON 作为字符串提取并使用 BigQuery JSON 函数来浏览文档。
BigQuery 使用新的 JSON 数据类型原生支持 JSON 数据,这样我们就可以将半结构化 JSON 提取到 BigQuery 中,而无需为 JSON 前期数据。希望这能解决您的问题。
https://cloud.google.com/bigquery/docs/reference/standard-sql/json-data
这个问题与
我有一堆 ndjson 文件,每天在 GCS 上生成,我想将其加载到 BQ table。
来自 file_1.json
的几行示例:
{"a": 1, "b": 2, "c": [1,2,4], "d": "string"}
{"a": 1, "c": [2, 4], "d": "some_string"}
{"a": 1, "e": 4}
一个file_2.json
的例子:
{"a": 4, "e": 6, "f": {"g": 7, "h": "str"}}
{"a": 1, "c": [2, 4], "f": {"g": 5}}
大多数字段是可选的,每个文件中的每个文件记录理论上可以包含任意字段组合(目前从大约 50 个中选择,但将来会改变和增加)。同名字段的内容应该(抛开任何错误)包含相同的数据类型。
我想将一组文件(某一天的所有文件)加载到 BQ table,其架构将由文件中所有字段的并集组成,具有 NULL 值其中一行没有对应字段的键。
我希望在没有需要维护的模式的情况下这样做。
我目前的尝试:
job_config = bigquery.LoadJobConfig(
write_disposition="WRITE_TRUNCATE",
create_disposition="CREATE_IF_NEEDED",
autodetect=True,
ignore_unknown_values=True,
schema_update_option="ALLOW_FIELD_ADDITION",
source_format="NEWLINE_DELIMITED_JSON"
)
uri = "gs://my-bucket/test/*.json"
load_job = client.load_table_from_uri(
uri,
table_id,
location="EU",
job_config=job_config,
)
load_job.result()
使用 autodetect=True
来避免明确指定架构,但由于自动检测从单个文件扫描多达 500 行 - 某些字段可能一开始不会创建。
我希望 schema_update_option="ALLOW_FIELD_ADDITION"
(ref here) 能满足我的需要,但它不起作用。
我尝试过的另一种选择:
# Instead of wildcard, get blob list and convert to uris
blobs = storage_client.get_bucket(BUCKET).list_blobs(prefix=FOLDER)
uris = [f"gs://{BUCKET}/{blob.name}" for blob in blobs if blob.name.endswith(".json")]
job_config = bigquery.LoadJobConfig(
write_disposition="WRITE_APPEND", #Will append file by file
create_disposition="CREATE_IF_NEEDED",
autodetect=True,
schema_update_option="ALLOW_FIELD_ADDITION",
source_format="NEWLINE_DELIMITED_JSON"
)
for uri in uris:
load_job = client.load_table_from_uri(
uri,
table_id,
location="EU",
job_config=job_config,
)
load_job.result()
这效率较低,我想 - 但无论如何它也不起作用 - 收到此错误:
BadRequest: 400 Provided Schema does not match Table my-bucket:test.test_diff_schema. Cannot add fields (field: f)
同样,我想 schema_update_option="ALLOW_FIELD_ADDITION"
会避免 - 但它似乎只适用于预定义的模式,而不适用于自动检测。
欢迎任何想法,提前致谢!
在自动检测中,BigQuery 读取了一堆第一行并尝试检测模式。在这第一个 运行 之后,模式已设置并且在整个摄取过程中无法更改。您可以使用“ignore_unknown_values”选项跳过与自动检测架构不匹配的值。
但它不会如你所愿。我知道 BigQuery 团队致力于更好的 JSON 集成。目前,我只能建议您将 JSON 作为字符串提取并使用 BigQuery JSON 函数来浏览文档。
BigQuery 使用新的 JSON 数据类型原生支持 JSON 数据,这样我们就可以将半结构化 JSON 提取到 BigQuery 中,而无需为 JSON 前期数据。希望这能解决您的问题。
https://cloud.google.com/bigquery/docs/reference/standard-sql/json-data