更新 BigQuery 架构/在 Java 中添加新列

Posted

技术标签:

【中文标题】更新 BigQuery 架构/在 Java 中添加新列【英文标题】:Update BigQuery Schema / Add New Column in Java 【发布时间】:2018-10-31 16:08:08 【问题描述】:

我需要通过 Java 更新 BigQuery 表架构。更改将是附加的(仅添加新列)。

我正在努力寻找实现这一目标的方法。在 Python 中可能是这样的:

table_ref = client.dataset(dataset_id).table(table_id)
table = client.get_table(table_ref)  # API request

original_schema = table.schema
new_schema = original_schema[:]  # creates a copy of the schema
new_schema.append(bigquery.SchemaField('phone', 'STRING'))

table.schema = new_schema
table = client.update_table(table, ['schema'])  # API request

在页面https://cloud.google.com/bigquery/docs/managing-table-schemas 上,声明使用补丁端点来执行此任务。

提出了一个改进补丁 API 的问题,但我不知道结果https://github.com/googleapis/google-cloud-java/issues/1564

这是补丁类文档的链接:https://developers.google.com/resources/api-libraries/documentation/bigquery/v2/java/latest/com/google/api/services/bigquery/Bigquery.Tables.Patch.html#set-java.lang.String-java.lang.Object-

任何帮助将不胜感激。谢谢

【问题讨论】:

【参考方案1】:

Java 中的想法与您分享的 Python 示例中的想法相同,即获取当前模式并向其中添加新列。您可以使用我准备的 sn-p 来实现这一点,您可以在下面看到:

// Instantiate the BQ client
BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

// Get the table, schema and fields from the already-existing table
Table table = bigquery.getTable(TableId.of("PROJECT_ID", "DATASET", "TABLE"));
Schema schema = table.getDefinition().getSchema();
FieldList fields = schema.getFields();

// Create the new field
Field newField = Field.of("column2", LegacySQLTypeName.STRING);

// Create a new schema adding the current fields, plus the new one
List<Field> field_list = new ArrayList<Field>();
for (Field f : fields) 
    field_list.add(f);

field_list.add(newField);
Schema newSchema = Schema.of(field_list);

// Update the table with the new schema
Table updatedTable = table.toBuilder().setDefinition(StandardTableDefinition.of(newSchema)).build().update();

此代码正在使用com.google.cloud.bigquery 包(请参阅其documentation here)。然后,它按照tables documentation 中的示例指定架构定义,最后更新它。

【讨论】:

非常感谢,会回复您是否有效,但看起来正是我需要的 很高兴能为您提供帮助!毕竟,如果答案对您有用,请考虑accepting and/or upvoting,以便社区看到它解决了您的问题。谢谢! 虽然这确实可以满足我的需要,但不幸的是,我使用的是不允许 com.google.cloud.bigquery 包的 Apache Beam 框架。相反,它使用了自己的梁包和另一个谷歌包:com.google.api.services.bigquery 我再次努力寻找通过这个包的方法,你碰巧知道吗?再次感谢 !这是***文档developers.google.com/resources/api-libraries/documentation/… 的链接 嗨@SimSimmer;谢谢你接受我的回答。我同意这适用于 BigQuery Java 客户端库,但不一定适用于 Apache Beam 环境。无论如何,如果这是一个完全不同的主题/问题,我建议您发布一个新问题,以便将其视为不同的问题,您可以添加适当的 Dataflow/Apache Beam 标签。 另外,为了让您可以开始处理这个单独的问题,我不确定是否有可能实现我的回答所建议的内容。相反,您可能必须使用 BigQuery 加载作业动态添加列,方法是使用新列更改架构,如 the documentation 中所述。【参考方案2】:

我还设法通过其他 Google BigQuery 包做到了:

    HttpTransport transport = new NetHttpTransport();
    JsonFactory jsonFactory = new JacksonFactory();
    GoogleCredential credential;
    try 
        credential = GoogleCredential.getApplicationDefault(transport,
                jsonFactory);
     catch (IOException e) 
        throw new RuntimeException(e);
    
    if (credential.createScopedRequired()) 
        credential = credential.createScoped(BigqueryScopes.all());
    

    Bigquery.Tables bqTables = new Bigquery.Builder(transport, jsonFactory, credential).build().tables();
    Bigquery.Tables.Get bqTableGet = bqTables.get(this.project, this.dataset, this.tablePrefix + strDate);

    Table bqTable = bqTableGet.execute();
    bqTable.setSchema(this.schema);

    Bigquery.Tables.Patch bqTablePatch = bqTables.patch(this.project, this.dataset, this.tablePrefix + strDate, bqTable);
    bqTablePatch.execute();

【讨论】:

以上是关于更新 BigQuery 架构/在 Java 中添加新列的主要内容,如果未能解决你的问题,请参考以下文章

尽管更新了架构,但 BigQuery 架构错误

使用 Python API 使用 RECORD 字段更新 BigQuery 架构

Bigquery:我们应该在模式更新后等待多长时间才能流式传输数据?

使用流式 API 更新新列后无法向 BigQuery 表插入新值

从 DataFlow 加载到现有 BigQuery 表时是不是可以更新架构?

使用间接架构更改更新 BigQuery 视图