我们有以下三个 JSON,其数据应加载到同一个表中:
{ "name": "tom", "customValues": [] }
{ "name": "joe", "customValues": { "member": "1" } }
{ "name": "joe", "customValues": { "year": "2020", "number": "3" } }
我们使用 python bigquery.LoadJobConfig
函数加载数据:
job_config = bigquery.LoadJobConfig(
schema=SCHEMA_MAP.get(bq_table) if autodetect == False else None,
source_format=bigquery.SourceFormat.NEWLINE_DELIMITED_JSON,
write_disposition=bigquery.WriteDisposition.WRITE_TRUNCATE if remove_old == True else bigquery.WriteDisposition.WRITE_APPEND,
autodetect=autodetect
)
SCHEMA_MAP
是一个数组字典,其中架构中的每个数组都对应我们的一个表。我们使用 python bigquery.SchemaField
函数在 python 中定义 BigQuery 架构。如果上面的 3 个 JSON 中的每一个都进入 3 个不同的表,我会将它们的表架构定义为:
SCHEMA_T1 = [
bigquery.SchemaField("name", "STRING"),
bigquery.SchemaField("customValues", "STRING", mode="REPEATED")
]
SCHEMA_T2 = [
bigquery.SchemaField("name", "STRING"),
bigquery.SchemaField("customValues", "RECORD", mode="REPEATED", fields=[
bigquery.SchemaField("member", "STRING")
])
]
SCHEMA_T3 = [
bigquery.SchemaField("name", "STRING"),
bigquery.SchemaField("customValues", "RECORD", mode="REPEATED", fields=[
bigquery.SchemaField("year", "STRING"),
bigquery.SchemaField("number", "STRING")
])
]
是否可以定义 customValues
列来在一个表中处理所有这 3 种不同的数据类型?如何为此定义模式?目前使用SCHEMA_T1
,上传T2或T3形式的数据,上传失败,返回错误Error while read data,错误信息:JSON parsing error in rowstarting在位置 0:为非记录字段指定的 JSON 对象:customValues
。其他模式的类似错误。 BigQuery 中是否有可用于此目的的通用 any json 字段?
最佳答案
由于 BigQuery 的 JSON
功能仍处于预览版中(请参阅 launch stages )。作为解决方法,您可以使用 bigquery 客户端中的 load_table_from_dataframe
从数据列加载数据,这些数据在推送到我们的工作表之前可能需要进行一些细化。
让我们看看您的场景,假设我们有一个包含原始数据的 data.json
文件:
data.json
[
{
"name": "tom",
"customValues": []
},
{
"name": "joe",
"customValues": {
"member": "1"
}
},
{
"name": "joe",
"customValues": {
"year": "2020",
"number": "3"
}
}
]
我们有一个关于 bigquery 的表需要填充。
create or replace table "my-project.my-dataset.a-table" (
name STRING,
customValues STRING
)
load.py
from google.cloud import bigquery
import pandas as pd
client = bigquery.Client()
table_id = "project-id.dataset-id.a-table"
df = pd.read_json('data.json')
df["customValues"]= df["customValues"].apply(str)
print(df.shape)
print(df.head())
job_config = bigquery.LoadJobConfig(source_format=bigquery.SourceFormat.PARQUET, autodetect=True)
job = client.load_table_from_dataframe(df, table_id, job_config=job_config)
job.result()
table = client.get_table(table_id)
print("Loaded {} rows and {} columns to {}".format(table.num_rows, len(table.schema), table_id))
输出
| **name** | **customValues** |
|----------|---------------------------------|
| tom | [] |
| joe | {'member': '1'} |
| joe | {'year': '2020', 'number': '3'} |
正如您所看到的,无论 customValues
的结构如何,我们都可以将其插入到我们的工作表(只有 2 列)中。我们将 json 数据加载到数据框中,然后使用 apply
更新数据类型列以适合我们的列类型。有关使用 apply
的更多信息,请访问此 link .
关于python - 加载到 BigQuery - 一列处理任意 json 字段(空数组、具有不同字段的字典等),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71139537/