【问题标题】:Insert data into BigQuery using native Insert query using Java使用本机将数据插入 BigQuery 使用 Java 插入查询
【发布时间】:2021-01-15 16:37:42
【问题描述】:

我使用 JAVA 使用 InsertAll 方法将行插入 BigQuery。它总是工作正常。但是当我们尝试从 JAVA 代码更新同一行时,出现以下错误,

com.google.cloud.bigquery.BigQueryException 对表 project123:mydataset.test 的 UPDATE 或 DELETE DML 语句会影响流缓冲区中的行,这是不受支持的

所以我尝试了 BigQueryConsole。

我使用 INSERT 查询插入一行,然后立即UPDATE 同一行。效果很好。

当我阅读 BIGQUERY 的文章时,他们提到了来自 JAVA 的 InsertAll 和使用 Streaming Buffer 的控制台的 INSERT 查询。在这种情况下,控制台查询执行应该会失败。

为什么控制台查询工作正常?但是从 Java InsertAll 开始,它向我抛出了一个异常。

如果有人帮助我了解确切的细节,那将非常有帮助。

如果有任何建议使用从 Java 而不是 InsertAll 到 BigQuery 的 Native insert 查询插入,这将是一个很大的帮助。

请找代码sn-p

首先使用以下代码 sn-p 将值插入 BigQuery

Map<String, Object> map = new HashMap<>();
map.put("1", "name");
map.put("2", "age");

BigQuery bQuery = BigQueryOptions.newBuilder().setCredentials(credentials).setProjectId(id)
            .build().getService();
InsertAllResponse response = bQuery .insertAll(InsertAllRequest.newBuilder(tableId).addRow(map).build());

一旦它被插入,我会尝试使用以下代码 sn-p 更新该表中的行

String updateQuery = String.format( "UPDATE `%s` SET name = \"%s\" WHERE age = \"%s\")", name, age);
QueryJobConfiguration queryConfig = QueryJobConfiguration.newBuilder(query).build();
bQuery.query(queryConfig);

插入工作正常。当我尝试更新相同的插入行时,出现流缓冲区错误。

提前致谢。

【问题讨论】:

  • 如果你能提供你得到的错误的截图或堆栈跟踪就更好了。会更容易理解问题
  • 感谢您的 cmets。我在上面发布的错误只是我在本地得到的。如果您遇到过此类错误,请添加您的建议
  • 您在哪里读到控制台上的 INSERT 在流中添加数据?
  • @guillaumeblaquiere 当我尝试通过控制台更新列(我使用插入查询添加)时工作正常。但是当我从 Java API 尝试同样的操作时,它会抛出 Streaming buffer 错误。

标签: java google-cloud-platform google-bigquery


【解决方案1】:

当您阅读 the documentation 时,很明显 insertAll 会执行流写入 BigQuery。

当您使用 INSERT DML (INSERT INTO &lt;table&gt; [VALUES....|SELECT...]) 时,您执行的是查询,而不是流写入。所以,数据管理是不一样的。性能也不同(Stream write 每秒最多可写入 100 万行,DML 是逐个查询,用更少的数据花费更多的时间)。

所以,我不知道您的代码以及您想要实现的目标。但如果你想使用普通查询(INSERT、UPDATE、DELETE),请使用查询 API。

编辑

我试图调整你的代码(但这是错误的,我做了一些假设),我可以向你提出这个建议。只需执行 QUERY,而不是 Load Job 或 Streaming 写入。

        String tableName = "YOUR_TABLE_NAME";
        
        String insertQuery = String.format("INSERT INTO %s(name, age) VALUES (1,2)", tableName);
        QueryRequest queryRequest = QueryRequest.builder(insertQuery).build();
        bQuery.query(queryRequest);


        String updateQuery = String.format( "UPDATE `%s` SET name = \"%s\" WHERE age = \"%s\")", tableName, name, age);
        queryRequest = QueryRequest.builder(updateQuery).build();
        bQuery.query(queryRequest);

【讨论】:

  • 非常感谢您的回复。您能告诉我查询 API 的详细信息吗?我在@guillaume blaquiere 上方添加了代码详细信息。
  • @Neela 如果您想更新行,请查看以下线程:stackoverflow.com/questions/48177241/… 并让我们知道它是否适合您
  • @Ines 非常感谢您的回复。我不想使用 MERGE 或 UPSERT 操作。从 Java 首先我必须将数据插入到 BigQuery 表中,然后我必须单独调用更新调用。我面临流媒体缓冲区错误。有什么方法可以像我们在 Update 中那样从 Java 调用 Native insert 方法查询?或任何其他在 Java 中使用作业的方式?
  • @guillaume blaquiere 非常感谢。让我试试这个并分享细节。
  • @guillaume blaquiere,能够插入到 bigquery 表中。谢谢你。但是你能告诉我它是否有任何限制,比如每天只插入 1000 条记录,或者如果我们在代码中使用这个本机插入查询,会有任何限制。我已阅读 DML 查询会有限制。请添加您的建议。
猜你喜欢
  • 1970-01-01
  • 2019-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-30
  • 1970-01-01
  • 2013-12-05
  • 1970-01-01
相关资源
最近更新 更多