您可以 SQL 填充 BigQuery 表并在同一个 API 调用中设置表列模式吗?
Posted
技术标签:
【中文标题】您可以 SQL 填充 BigQuery 表并在同一个 API 调用中设置表列模式吗?【英文标题】:Can you SQL populate a BigQuery table and set the table column modes in the same API call? 【发布时间】:2019-01-10 12:01:58 【问题描述】:我正在使用 Google App Script 通过 BigQuery 迁移数据,但我遇到了一个问题,因为我用来执行 WRITE_TRUNCATE 加载的 SQL 导致目标表以 NULLABLE 列模式重新创建,而不是他们以前的 REQUIRED 模式。
在使用元数据补丁加载数据后尝试将模式更改为 REQUIRED 会导致错误,即使列不包含任何空值。
我考虑通过删除表并使用相同的 REQUIRED 模式重新创建它来解决此问题,然后使用 WRITE_APPEND 而不是 WRITE_TRUNCATE 加载数据。但这是不可能的,因为用户希望在他们的 SQL 中拥有相同的源表和目标表。
有谁知道是否可以定义一个包含输出架构信息/元数据的BigQuery.Jobs.insert
请求?
如果不可能,我能看到的唯一替代方法是使用我原来的 WRITE_APPEND 解决方法,但在进程中添加一个临时表,以允许目标表出现在源 SQL 中。但是,如果可以避免这种情况,那就太好了。
其他信息:
我确实尝试了不同的方式来设置架构信息,但是当他们没有返回错误消息时,架构似乎被忽略了。
IE。这是我传递给BigQuery.Jobs.insert
的json@
jsnConfig =
"configuration":
"query":
"destinationTable":
"projectId":"my-project",
"datasetId":"sandbox_dataset",
"tableId":"hello_world"
,
"writeDisposition":"WRITE_TRUNCATE",
"useLegacySql":false,
"query":"SELECT COL_A, COL_B, '1' AS COL_C, COL_TIMESTAMP, COL_REQUIRED FROM `my-project.sandbox_dataset.hello_world_2` ",
"allowLargeResults":true,
"schema":
"fields":
[
"description":"Desc of Column A",
"type":"STRING",
"mode":"NULLABLE",
"name":"COL_A"
,
"description":"Desc of Column B",
"type":"STRING",
"mode":"REQUIRED",
"name":"COL_B"
,
"description":"Desc of Column C",
"type":"STRING",
"mode":"REPEATED",
"name":"COL_C"
,
"description":"Desc of Column Timestamp",
"type":"INTEGER",
"mode":"NULLABLE",
"name":"COL_TIMESTAMP"
,
"description":"Desc of Column Required",
"type":"STRING",
"mode":"REQUIRED",
"name":"COL_REQUIRED"
]
var job = BigQuery.Jobs.insert(jsnConfig, "my-project");
结果是新的或现有的 hello_world 表被截断并加载了查询中指定的数据(因此正在读取部分 json 包),但未按照定义添加列描述和模式架构部分。它们在表中只是空白和 NULLABLE。
更多
当我使用Googles API page for BigQuery.Jobs.Insert 测试上面的 REST 请求时,它突出显示请求中的“架构”属性无效。我认为如果您从文件加载数据(即BigQuery.Jobs.Load
)似乎可以定义架构,但如果您使用 SQL 源将数据放入,它似乎不支持该功能。
【问题讨论】:
【参考方案1】:在此处查看文档:https://cloud.google.com/bigquery/docs/schemas#specify-schema-manual-python
您可以通过加载作业传递架构对象,这意味着您可以将字段设置为 mode=REQUIRED
【讨论】:
不幸的是,我尝试了这种方法,但架构信息似乎被忽略了。我会将详细信息添加到我的原始帖子中,以便更好地显示它。【参考方案2】:这是你应该使用的命令:
bq --location=[LOCATION] load --source_format=[FORMAT] [PROJECT_ID]:[DATASET].[TABLE] [PATH_TO_DATA_FILE] [PATH_TO_SCHEMA_FILE]
正如@Roy 回答的那样,this is done via load only。可以输出这条命令的日志吗?
【讨论】:
不幸的是,数据是来自 BigQuery 源表的inserted
,而不是来自 GCS 源文件的 loaded
。所以我不能像你和 Royzipuff 建议的那样使用 load 命令:(
如何先导出为 CSV 或 JSON 到 Cloud Storage,然后再从那里上传到 BigQuery?
是的,我考虑过,但添加完整输出步骤(即 A->C->B 的效率低下)非常不吸引人。当我提出它时,如果模式不能保留在插入中,首选是牺牲模式,而不是增加额外的开销。以上是关于您可以 SQL 填充 BigQuery 表并在同一个 API 调用中设置表列模式吗?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Cloud 功能将 TXT 文件转换为 CSV 并在 Google BigQuery 中填充数据
如何在 BigQuery 中使用标准 SQL 查询 GA RealtimeView?
将excel数据导入sql server数据库表并在gridview中显示