首页 > 解决方案 > 您可以 SQL 填充 BigQuery 表并在同一个 API 调用中设置表列模式吗?

问题描述

我正在使用 Google App Script 通过 BigQuery 迁移数据,我遇到了一个问题,因为我用来执行 WRITE_TRUNCATE 加载的 SQL 导致使用 NULLABLE 的列模式而不是之前的模式重新创建目标表需要的。

在使用元数据补丁加载数据后尝试将模式更改为 REQUIRED 会导致错误,即使列不包含任何空值也是如此。

我考虑通过删除表并使用相同的 REQUIRED 模式重新创建它来解决此问题,然后使用 WRITE_APPEND 而不是 WRITE_TRUNCATE 加载数据。但这是不可能的,因为用户希望在他们的 SQL 中拥有相同的源表和目标表。

有谁知道是否可以定义一个BigQuery.Jobs.insert包含输出模式信息/元数据的请求?

如果不可能,我能看到的唯一替代方法是使用我原来的 WRITE_APPEND 解决方法,但在进程中添加一个临时表,以允许目标表出现在源 SQL 中。但是,如果可以避免这种情况,那就太好了。

附加信息

我确实尝试了不同的设置模式信息的方法,但是当它们没有返回错误消息时,模式似乎被忽略了。即这是我传入的 jsonBigQuery.Jobs.insert

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。

更多的

当我使用BigQuery.Jobs.Insert 的 Googles API 页面测试上面的 REST 请求时,它突出显示请求中的“模式”属性无效。我认为如果您从文件加载数据,似乎可以定义架构,即,BigQuery.Jobs.Load但如果您使用 SQL 源将数据放入,它似乎不支持该功能。

标签: google-apps-scriptgoogle-apigoogle-bigquery

解决方案


请参阅此处的文档:https ://cloud.google.com/bigquery/docs/schemas#specify-schema-manual-python

您可以通过加载作业传递模式对象,这意味着您可以将字段设置为 mode=REQUIRED


推荐阅读