【问题标题】:How to get query result in Json form using Java API of Google Bigquery如何使用 Google Bigquery 的 Java API 以 Json 形式获取查询结果
【发布时间】:2017-05-24 05:56:26
【问题描述】:

我正在使用 Google Bigquery V2 Java API。我无法找到以 JSON 格式获取查询结果的方法。 在 Bigquery Web UI 中,我们可以看到这种 JSON 和表格形式的结果。见截图。

有没有办法使用 Java API 将 GetQueryResultsResponse 作为 JSON。

【问题讨论】:

    标签: java google-bigquery


    【解决方案1】:

    一种选择是将TO_JSON_STRING function 应用于查询结果。例如,

    #standardSQL
    SELECT TO_JSON_STRING(t)
    FROM (
      SELECT x, y
      FROM YourTable
      WHERE z = 10
    ) AS t;
    

    如果您希望表格的所有列都为 JSON,您可以使用更简单的形式:

    #standardSQL
    SELECT TO_JSON_STRING(t)
    FROM YourTable AS t
    WHERE z = 10;
    

    【讨论】:

    • 这并不能解决我的问题。我们可以使用 JAVA API 获取 JSON 格式的查询结果吗??
    • Google 如何在 Web UI 上显示 JSON 结果。它是否将结果响应显式转换为 JSON 格式?
    • 你能描述一下为什么这不能解决你的问题吗?客户端库从 BigQuery 服务获取 JSON 响应,并将它们转换为每种语言(Java、Python 等)的本机表示。如果你想要结果为 JSON 字符串,你可以使用这个函数。
    • 我在 API 级别工作。对我来说,我无法更改用户的查询或不想强制用户使用 TO_JSON_STRING 函数。有没有办法将响应的本机表示转换为 JSON 字符串。类似于 Bigquery Web UI。
    • 我也有同样的问题。我也想避免使用 TO_JSON_STRING 函数,因为我不仅要修改原始 SQL,而且这个函数的 json 输出格式与导出表的 json 输出格式不同。命令bq query --format json --project_id myProject "select * from sandbox.keweiquerytable"可以查询一个表,结果为json格式。所以我想应该有一种方法可以在 REST 或 JAVA API 中做到这一点。有人知道吗?
    【解决方案2】:

    我正在使用服务帐号访问 BigQuery REST API 以获取 JSON 格式的响应。

    要使用服务帐户,您必须转到凭据 (https://console.cloud.google.com/apis/credentials) 并选择一个项目。

    你会得到这样的下拉菜单:

    为您的项目创建一个服务帐户并下载 JSON 格式的机密文件。将 JSON 文件保存在文件系统中并设置其路径。检查下图以设置文件路径:

    所以,现在您要做的就是使用 JAVA 客户端 api 来使用 Big Query REST API。

    这是我一直用于我的项目的一个简单解决方案。

    package com.example.bigquery;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.util.Arrays;
    
    import org.apache.log4j.Logger;
    
    import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
    import com.google.api.client.http.GenericUrl;
    import com.google.api.client.http.HttpContent;
    import com.google.api.client.http.HttpHeaders;
    import com.google.api.client.http.HttpRequest;
    import com.google.api.client.http.HttpRequestFactory;
    import com.google.api.client.http.HttpResponse;
    import com.google.api.client.http.HttpTransport;
    import com.google.api.client.http.javanet.NetHttpTransport;
    import com.google.api.client.http.json.JsonHttpContent;
    import com.google.api.client.json.JsonFactory;
    import com.google.api.client.json.jackson2.JacksonFactory;
    import com.google.common.io.CharStreams;
    
    public class BigQueryDemo {
    
        private static final String QUERY_URL_FORMAT = "https://www.googleapis.com/bigquery/v2/projects/%s/queries" + "?access_token=%s";
    
        private static final String QUERY = "query";
    
        private static final String QUERY_HACKER_NEWS_COMMENTS = "SELECT * FROM [bigquery-public-data:hacker_news.comments] LIMIT 1000";
    
        private static final Logger logger = Logger.getLogger(BigQueryDemo.class);
    
        static GoogleCredential credential = null;
        static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
        static final JsonFactory JSON_FACTORY = new JacksonFactory();
        static {
            // Authenticate requests using Google Application Default credentials.
            try {
                credential = GoogleCredential.getApplicationDefault();
                credential = credential.createScoped(Arrays.asList("https://www.googleapis.com/auth/bigquery"));
                credential.refreshToken();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public static void implicit() {
            String projectId = credential.getServiceAccountProjectId();
            String accessToken = generateAccessToken();
            // Set the content of the request.
            Dataset dataset = new Dataset().addLabel(QUERY, QUERY_HACKER_NEWS_COMMENTS);
            HttpContent content = new JsonHttpContent(JSON_FACTORY, dataset.getLabels());
            // Send the request to the BigQuery API.
            GenericUrl url = new GenericUrl(String.format(QUERY_URL_FORMAT, projectId, accessToken));
            logger.debug("URL: " + url.toString());
            String responseJson = getQueryResult(content, url);
            logger.debug(responseJson);
        }
    
        private static String getQueryResult(HttpContent content, GenericUrl url) {
            String responseContent = null;
            HttpRequestFactory requestFactory = HTTP_TRANSPORT.createRequestFactory();
            HttpRequest request = null;
            try {
                request = requestFactory.buildPostRequest(url, content);
                request.setParser(JSON_FACTORY.createJsonObjectParser());
                request.setHeaders(
                        new HttpHeaders().set("X-HTTP-Method-Override", "POST").setContentType("application/json"));
                HttpResponse response = request.execute();
                InputStream is = response.getContent();
                responseContent = CharStreams.toString(new InputStreamReader(is));
            } catch (IOException e) {
                logger.error(e);
            }
            return responseContent;
        }
    
        private static String generateAccessToken() {
            String accessToken = null;
            if ((System.currentTimeMillis() > credential.getExpirationTimeMilliseconds())) {
                accessToken = credential.getRefreshToken();
            } else {
                accessToken = credential.getAccessToken();
            }
            System.out.println(accessToken);
            return accessToken;
        }
    }
    

    以下是代码的 Github 链接:https://github.com/vslala/BigQueryRestSample

    这只是一个从 BQ REST API 获取 JSON 数据的演示项目。不要直接在你的项目中使用它。 如果您有任何问题,请告诉我。

    【讨论】:

      猜你喜欢
      • 2018-07-30
      • 2018-07-12
      • 1970-01-01
      • 1970-01-01
      • 2017-09-08
      • 1970-01-01
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多