您可以 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中显示

使用 PHP 和 JavaScript 动态搜索 SQL 表并在 HTML 上显示

从访问数据库中选择表并在c#上插入sql多个表

如何连接多个表并填充到 datagridview 控件中?